Search code examples
androidlistviewandroid-listviewviewlistviewitem

When updating a ListView of CheckBox items, is it better to update the individual view, or notifyDataSetChanged() and invalidateViews()?


Both of these work, but is one better than the other?

Update individual view:

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
    MyObject item = (MyObject) adapterView.getItemAtPosition(i);
    boolean isChecked = item.isChecked();
    item.setChecked(!isChecked);
    ((CheckBox)view.findViewById(R.id.checkBox)).setChecked(!isChecked);
}

Update all views:

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
    MyObject item = (MyObject) adapterView.getItemAtPosition(i);
    item.setChecked(!item.isChecked());
    adapter.notifyDataSetChanged();
    getListView().invalidateViews();
}

Solution

  • Updating individual view is bad, because findViewById take a long time (vs other methods) to execute and because there will be a case when you want to update a lot of list items (say, 20 items). You will not want to update your items one by one - it will take a lot of time and resources.

    Now, take a look at your code when updating all items :

    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        MyObject item = (MyObject) adapterView.getItemAtPosition(i);
        item.setChecked(!item.isChecked());
        adapter.notifyDataSetChanged();
        getListView().invalidateViews(); //you can remove this line, read my explanation below
    }
    

    You called notifyDataSetChanged and invalidateViews, which is a waste in your case. Why?

    notifyDataSetChanged will refresh the listview if an item's value/data has been changed.

    Example : checkbox's value changed - like in your case.

    Meanwhile, invalidateViews will refresh the listview if an item's properties has been changed.

    Example : textview's color or text size changed.

    Hence, in your case there is no need to call getListView().invalidateViews(); because no item's properties is changed, the one and only that changed is item's value/data.

    UPDATE BY REQUEST :

    This is an example where you should (and only need to) call invalidateViews :

    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        MyObject item = (MyObject) adapterView.getItemAtPosition(i); //lets say item is TextView
        item.setTextColor(Color.RED);
        item.setTextSize(2);    
        item.setBackgroundColor(Color.BLUE);
        getListView().invalidateViews();
    }
    

    Because setTextSize, setBackgroundColor, and setTextColor just change properties, not value/data.