Android. How Does Notifydatasetchanged() Method and Listviews Work

Android. How does notifyDataSetChanged() method and ListViews work?

I've figured it out. I couldn't understand how the hell the adapter started and how did it know where to get the data from. When i extended the BaseAdapter class, in the constructor of that class I initialized the list of items that I wanted to see in the ListView. But I couldn't figure out how these values would be used and when.

So here's the thing !!! :

In the BaseAdapter there are some methods that need to be overridden. Among these, there is getCount().

When the ListView is created and whatnot, it calls getCount(). If this returns a value different than 0 (I returned the size of the ArrayList which I've previously initialized in the constructor), then it calls getView() enough times to fill the screen with items. For instance, I initialized the ArrayList with 20 items. Because only 8 items initially fit on the screen, getView() was called 8 times, each time asking for the position it required for me to return (more precisely it wanted to know how the row would look like in the list on that specific position, what data it needed to contain). If I scroll down the list, getView() gets called over and over again, 'til I hit the end of the list, in my case 20 items / rows.

What notifyDataSetChanged() does is ... when called, it looks at what items are displayed on the screen at the moment of its call (more precisely which row indexes ) and calls getView() with those positions.

i.e. if you're displaying the first 8 items in the list (so those are the ones visible on the screen) and you add another item between the 2nd and 3rd item in the list and you call notifyDataSetChanged() then getView() is called 8 times, with positions starting from 0 and ending with 7, and because in the getView() method you're getting data from the ArrayList then it will automatically return the new item inserted in the list alongside 7 out of the previous 8 (7 and not 8 because the last item went one position down, so it is not visible anymore), and the ListView will redraw, or whatever, with these items.

Also, important to specify is that if you've implemented getView() correctly, you'll end up recycling the items (the objects) already displayed (instead of creating new ones). See this video at around 12:00 minutes to see the correct way to implement getView()

I've figured all this out by placing calls to LogCat in every method and following what was going on.

Hope this helps someone who's just now starting to understand how ListViews work.

P.S. This example also helped me a lot to understand.

UPDATE

Nowadays ListViews are not really used anymore. Android came out with the RecyclerView which does the recycling of the views for you, but knowing the basics of a ListView helps with understanding the RecyclerView.

Here's a link for reference: https://developer.android.com/guide/topics/ui/layout/recyclerview

How android's BaseAdapter notifyDataSetChanged method work?


Supposed I changed the 3rd element in my string array (array data for
the listview), what "any View reflecting the data set should refresh
itself" means ?

It means that any view which shows/is based on/uses that data(the string array in your case) should be invalidated(remeasured, redrawn) in order to show the user the new set of data.

Does the 3rd view item in my list view be notified?

No, the parent ListView will be notified. When you set the adapter on a ListView, an observer(from the ListView) will be set for that adapter. Calling notifyDataSetChanged on the adapter will announce that observer from the ListView that something has happen to the data. At this moment the ListView will recreate the rows to show the new data.

Also, how is notifyDataSetChanged() and getView() concerned ?

I'm not sure I understand what you ask. The getView method of an adapter is used by the ListView to obtain a new row each time this is required. When you call notifyDataSetChanged on the adapter this will trigger the observer in the ListView. As it's time to recreate the list, the ListView will call the getView method of the adapter to show the necessary number of rows(the ones visible on the screen). So each time you call notifyDataSetChanged the getView method will be called for the visible rows.

What does notifyDataSetChanged() do on recyclerview? why it keeps adding new data everytime i call notifyDataSetChanged()?


Your first question

What does notifyDataSetChanged() do on recyclerview?

From Docs

notifyDataSetChanged

  1. Notify any registered observers that the data set has changed.

  2. There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred. Structural changes are when items are inserted, removed or moved within the data set.

  3. means whenever you called notifyDataSetChanged() it call onBindViewHolder()

Your second question

why it keeps adding new data everytime i call notifyDataSetChanged()?

Because you are using adding new data in your adapterChart using below line
adapterChart.addData(mItemsChart); inside Your onBindViewHolder

it means whenever your onBindViewHolder is called you are adding data in your adapterChart

Android ListView - difference between adapter.notifyDataSetChanged and using new adapter

When you call notifyDataSetChanged(), getView() is called the same number of times. However, since the adapter is the same, these views can be reused (i.e. passed as convertView).

That cannot be done when supplying a new adapter, because the ListView cannot know for sure that the new adapter uses the same layouts. So the recycler is cleared, and all rows must be created from scratch (which is far costlier than reusing them).

(This performance point is moot if you ignore the supplied convertView and always create/inflate a new view -- but that's a bad idea anyway).

Is notifyDataSetChanged() really necessary when updating ListView

The adapter needs to know that the data has changed in order to refresh itself so it's necessary to do so. The question is why you need an alternative in the first place!

However if you need it to be more performant you can notify the specific item got changed not the whole items by using RecyclerView.Adapter's notifyItemChanged (int position) and this is not available if you still using ListView.

Android ListView notifyDataSetChanged() dont refresh the list

replace :

credentials.clear();

with :

adapter.clear()

and whenever you want adding data to the list use:

adapter.addAll(credentials)

or

adapter.insert("new data")

its must fix your problem.

last point : adapter.notifyDataSetChanged(); it not necessary because it is inside the body of adapter methods. good luck.

Android notifyDataSetChanged not working

create a method in your adapter like:

 public void updateList(){
notifyDataSetChanged()
}

and call this method when you want to refresh the list



Related Topics



Leave a reply



Submit