Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better to recreate listview adapter or to clear and repopulate?

If I have a ListView with a CustomAdapter and let's say I have this refresh() method that refreshes the list with new results, should I:

  1. Call new CustomAdapter(...) upon initialization, and every time I call refresh(), I use adapter.clear() and adapter.add(...)

  2. Call new CustomAdapter(...) every time I call refresh()

Basically, I'm asking, is it better to recreate an adapter everytime I load new results or is it better to clear the results in existing adapter and add the entire list to it?

like image 470
raybaybay Avatar asked Jul 19 '14 01:07

raybaybay


2 Answers

I think if you're going to use adapters as they were intended, then you'll update the adapter's data and call notifyDataSetChanged() on it.

If you look at the API for something like ArrayAdapter, it has numerous methods like clear(), add(), addAll(), notifyDataSetChanged() and so forth that are there to guide you towards a certain use of the API.

By using these methods, not only does it make your code compliant with its intended usage, it also makes it easier to understand and familiar to others that are trying to understand your code.

So basically, I would only recreate the adapter as a last resort.

like image 187
JDJ Avatar answered Oct 10 '22 19:10

JDJ


It is definitely better to call notifyDataSetChanged() on the original adapter than setting a new one.

The reason is performance: ListView uses view recycling to avoid creating new item views as you scroll. When you set a new adapter, these recycled views are discarded, which means they must be recreated from scratch for the next layout pass. Take a look at the code of ListView.setAdapter():

@Override
public void setAdapter(ListAdapter adapter) {
    if (mAdapter != null && mDataSetObserver != null) {
        mAdapter.unregisterDataSetObserver(mDataSetObserver);
    }

    resetList();
    mRecycler.clear();

    ...

This is completely logical behavior, since the ListView supposes that the views the new adapter will use are incompatible with the ones returned by the previous adapter (in any case, it cannot assume that they will be compatible). So they're thrown away.

Therefore, if you set a new adapter each time, you're incurring an unnecessary performance cost (recreating all the current views).

Also, if you wrote a custom adapter, you don't necessarily have to call add() individually (as with, say, ArrayAdapter). You can just replace the internal data collection with the new one and call notifyDataSetChanged() afterwards.

like image 30
matiash Avatar answered Oct 10 '22 21:10

matiash