Updating the list view when the adapter data changes

Android

Android Problem Overview


When the data associated with array adapter is changed, invalidating the listview is sufficient to show the updated values? Following piece of code is not working, did i misunderstood something here.?

public class ZeroItemListActivity extends Activity {
	private ArrayList<String> listItems=new ArrayList<String>();
	private ListView mMyListView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMyListView=(ListView) findViewById(R.id.MyListView);
        mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
    }
    public void addItem(View v){
    	listItems.add("list Item");
    	mMyListView.invalidate();
    }
}

Layout used :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="@string/hello" />
	<ListView android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:id="@+id/MyListView"></ListView>
	<Button android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:id="@+id/AddItemsButton"
		android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>

Android Solutions


Solution 1 - Android

substitute:

mMyListView.invalidate();

for:

((BaseAdapter) mMyListView.getAdapter()).notifyDataSetChanged(); 

If that doesnt work, refer to this thread: https://stackoverflow.com/questions/4088862/android-list-view-refresh/4088889#4088889

Solution 2 - Android

Change this line:

mMyListView.setAdapter(new ArrayAdapter<String>(this, 
                           android.R.layout.simple_list_item_1, 
                           listItems));

to:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                   android.R.layout.simple_list_item_1, 
                                   listItems)
mMyListView.setAdapter(adapter);

and after updating the value of a list item, call:

adapter.notifyDataSetChanged();

Solution 3 - Android

invalidate(); calls the list view to invalidate itself (ie. background color)
invalidateViews(); calls all of its children to be invalidated. allowing you to update the children views

I assume its some type of efficiency thing preventing all of the items to constantly have to be redraw if not necessary.

Solution 4 - Android

I found a solution that is more efficient than currently accepted answer, because current answer forces all list elements to be refreshed. My solution will refresh only one element (that was touched) by calling adapters getView and recycling current view which adds even more efficiency.

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      // Edit object data that is represented in Viewat at list's "position"
      view = mAdapter.getView(position, view, parent);
    }
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSureshView Question on Stackoverflow
Solution 1 - AndroidblindstuffView Answer on Stackoverflow
Solution 2 - Androidritesh4326View Answer on Stackoverflow
Solution 3 - Androiduser3044482View Answer on Stackoverflow
Solution 4 - AndroidIgnasView Answer on Stackoverflow