Dynamic Listview in Android App

Dynamically add items to list view using custom adapter for Android app

  1. In your adapter change the Locations data[] from array to
    ArrayList<Location> and override the appropriate constructor
  2. In your activity, make your variable data a field (type ArrayList<Location>)
  3. When you add a location you can use data.add(location)
  4. Then you can call notifyDatasetChanged() on your adapter

Example code.

How to dynamically update a ListView on Android

First, you need to create an XML layout that has both an EditText, and a ListView.

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<!-- Pretty hint text, and maxLines -->
<EditText android:id="@+building_list/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>

<!-- Set height to 0, and let the weight param expand it -->
<!-- Note the use of the default ID! This lets us use a
ListActivity still! -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>

</LinearLayout>

This will lay everything out properly, with a nice EditText above the ListView. Next, create a ListActivity as you would normally, but add a setContentView() call in the onCreate() method so we use our recently declared layout. Remember that we ID'ed the ListView specially, with android:id="@android:id/list". This allows the ListActivity to know which ListView we want to use in our declared layout.

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.filterable_listview);

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}

Running the app now should show your previous ListView, with a nice box above. In order to make that box do something, we need to take the input from it, and make that input filter the list. While a lot of people have tried to do this manually, most ListView Adapter classes come with a Filter object that can be used to perform the filtering automagically. We just need to pipe the input from the EditText into the Filter. Turns out that is pretty easy. To run a quick test, add this line to your onCreate() call

adapter.getFilter().filter(s);

Notice that you will need to save your ListAdapter to a variable to make this work - I have saved my ArrayAdapter<String> from earlier into a variable called 'adapter'.

Next step is to get the input from the EditText. This actually takes a bit of thought. You could add an OnKeyListener() to your EditText. However, this listener only receives some key events. For example, if a user enters 'wyw', the predictive text will likely recommend 'eye'. Until the user chooses either 'wyw' or 'eye', your OnKeyListener will not receive a key event. Some may prefer this solution, but I found it frustrating. I wanted every key event, so I had the choice of filtering or not filtering. The solution is a TextWatcher. Simply create and add a TextWatcher to the EditText, and pass the ListAdapter Filter a filter request every time the text changes. Remember to remove the TextWatcher in OnDestroy()! Here is the final solution:

private EditText filterText = null;
ArrayAdapter<String> adapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.filterable_listview);

filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}

private TextWatcher filterTextWatcher = new TextWatcher() {

public void afterTextChanged(Editable s) {
}

public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}

public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}

};

@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}

Dynamically add items in list view

For this Just use the example given below:
For Instance you are Adding Some Strings into your List

So Create a ListArray like this

ArrayList<String> listItems = new ArrayList<String>();

now whenever you want to add certain string into list just do this thing

  EditText editText = (EditText) findViewById(R.id.edit);
listItems.add("my string"); OR
listItems.add(editText.getText.toString()); //incase if you are getting string value from editText and adding it into the list

Use this Xml inside your linear layout in main.xml

  <EditText android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

Now when you have added one item dynamically then call this

  adapter.notifyDataSetChanged();

The above will update your list and display the upadted list.

For more info about this see the following links:

http://www.androidpeople.com/android-custom-listview-tutorial-part-1

http://www.androidpeople.com/android-custom-listview-tutorial-part-2

http://www.androidpeople.com/android-custom-dynamic-listview-%E2%80%93part3

In these tutorials you can replace String[] with ArrayList as given at the top of the answer ook and when you want to add any item just simply use the second code snippet.

Thanks

sHaH

Dynamic ListView in Android app

To add new item to your list dynamically you have to get adapter class from your ListActivity and simply add new elements. When you add items directly to adapter, notifyDataSetChanged is called automatically for you - and the view updates itself.

You can also provide your own adapter (extending ArrayAdapter) and override the constructor taking List parameter. You can use this list just as you use adapter, but in this case you have to call adapter.notifyDataSetChanged() by yourself - to refresh the view.

Please, take a look at the example below:

public class CustomList extends ListActivity {
private LayoutInflater mInflater;
private Vector<RowData> data;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mInflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
data = new Vector<RowData>();
RowData rd = new RowData("item1", "description1");
data.add(rd);
rd = new RowData("item2", "description2");
data.add(rd);
rd = new RowData("item2", "description3");
data.add(rd);

CustomAdapter adapter = new CustomAdapter(this, R.layout.custom_row,R.id.item, data);
setListAdapter(adapter);
getListView().setTextFilterEnabled(true);
}

public void onListItemClick(ListView parent, View v, int position, long id) {
CustomAdapter adapter = (CustomAdapter) parent.getAdapter();
RowData row = adapter.getItem(position);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(row.mItem);
builder.setMessage(row.mDescription + " -> " + position );
builder.setPositiveButton("ok", null);
builder.show();
}

/**
* Data type used for custom adapter. Single item of the adapter.
*/
private class RowData {
protected String mItem;
protected String mDescription;

RowData(String item, String description){
mItem = item;
mDescription = description;
}

@Override
public String toString() {
return mItem + " " + mDescription;
}
}

private class CustomAdapter extends ArrayAdapter<RowData> {

public CustomAdapter(Context context, int resource,
int textViewResourceId, List<RowData> objects) {
super(context, resource, textViewResourceId, objects);

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;

//widgets displayed by each item in your list
TextView item = null;
TextView description = null;

//data from your adapter
RowData rowData= getItem(position);

//we want to reuse already constructed row views...
if(null == convertView){
convertView = mInflater.inflate(R.layout.custom_row, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
//
holder = (ViewHolder) convertView.getTag();
item = holder.getItem();
item.setText(rowData.mItem);

description = holder.getDescription();
description.setText(rowData.mDescription);

return convertView;
}
}

/**
* Wrapper for row data.
*
*/
private class ViewHolder {
private View mRow;
private TextView description = null;
private TextView item = null;

public ViewHolder(View row) {
mRow = row;
}

public TextView getDescription() {
if(null == description){
description = (TextView) mRow.findViewById(R.id.description);
}
return description;
}

public TextView getItem() {
if(null == item){
item = (TextView) mRow.findViewById(R.id.item);
}
return item;
}
}

}

You can extend the example above and add "more" button - which just add new items to your adapter (or vector).
Regards!



Related Topics



Leave a reply



Submit