Dynamically add items to list view using custom adapter for Android app
- In your adapter change the
Locations data[]
from array toArrayList<Location>
and override the appropriate constructor - In your activity, make your variable
data
a field (typeArrayList<Location>
) - When you add a location you can use
data.add(location)
- 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
How to Fill Data in a Jtable with Database
How to Get Eclipse to Use a Different Compiler Version for Java
Intellij Fat One Jar Artifact Does Not Generate a Working Output
How Do Hashtables Deal with Collisions
Getextractedtext on Inactive Inputconnection Warning on Android
Duplicated Entries in Listview
Reading a JSON Array in Android
Android Heterogeneous Gridview Like Pinterest
Android Simpledateformat, How to Use It
Android Web Scraping with a Headless Browser
How to Change the Text Color in a String to Multiple Colors in Java
Openssl Is Not Recognized as an Internal or External Command
Android: Countdowntimer Skips Last Ontick()!
Java.Io.Ioexception:No Authentication Challenges Found
Resize Image to Full Width and Fixed Height with Picasso