Android 安卓。notifyDataSetChanged() 方法和 ListViews 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12229817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:05:37  来源:igfitidea点击:

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

androidandroid-listviewandroid-adapterview

提问by AndreiBogdan

I am trying to understand the ListViewconcept and how it works and I'm trying to create my own adapter which extends BaseAdapter. For ArrayAdapterfor instance, there is the notifyDataSetChanged()method which should be called after you've updated the array list which holds all your data, in order to refresh the ListView.

我正在尝试了解这个ListView概念及其工作原理,并且我正在尝试创建自己的适配器,它扩展了BaseAdapter. 对于ArrayAdapter例如,有notifyDataSetChanged()你已经更新了其持有的所有数据数组列表后,为了刷新应该被调用的方法ListView

But I am creating my own subclass of BaseAdapter. That method is not available to me, or is it? How do i implement this method? Basically, what does that method do exactly, maybe I'll understand then.

但我正在创建我自己的BaseAdapter. 那个方法对我不可用,是吗?我如何实现这个方法?基本上,该方法究竟做了什么,也许我会明白。

In case of the ArrayAdapteri'm guessing it looks at what position the ListViewis currently displaying and it checks if it's the same one as in the ArrayListafter it was updated? Or...

如果ArrayAdapter我猜它会查看ListView当前显示的位置,并检查它是否与ArrayList更新后的位置相同?或者...

It says that the method:

它说该方法:

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

通知附加的观察者基础数据已更改,任何反映数据集的视图都应自行刷新。

But how exactly does it refresh itself?

但它究竟是如何自我刷新的呢?

Can someone explain please?

有人可以解释一下吗?

回答by AndreiBogdan

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 BaseAdapterclass, 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.

我想通了。我无法理解适配器到底是如何启动的,以及它是如何知道从哪里获取数据的。当我扩展BaseAdapter该类时,在该类的构造函数中,我初始化了我想在ListView. 但我无法弄清楚这些值将如何使用以及何时使用。

So here's the thing !!! :

所以事情来了!!!:

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

其中BaseAdapter有一些方法需要重写。其中,有getCount()

When the ListViewis 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 ArrayListwith 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.

ListView创建等等时,它会调用getCount(). 如果这返回一个不为 0 的值(我返回了我之前在构造函数中初始化的 ArrayList 的大小),那么它会调用getView()足够多的时间来用项目填充屏幕。例如,我ArrayList用 20 个项目初始化了。因为最初只有 8 个项目适合屏幕,getView()被调用了 8 次,每次都要求我返回所需的位置(更准确地说,它想知道该行在该特定位置的列表中的样子,什么数据它需要包含)。如果我向下滚动列表,getView()就会一遍又一遍地调用,直到我到达列表的末尾,在我的情况下为 20 个项目/行。

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.

什么notifyDataSetChanged()是......当被调用时,它会查看调用时屏幕上显示的项目(更准确地说是哪些行索引)并getView()使用这些位置进行调用。

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 ArrayListthen 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 ListViewwill redraw, or whatever, with these items.

即,如果您正在显示列表中的前 8 个项目(因此这些是屏幕上可见的项目),并且您在列表中的第 2 个和第 3 个项目之间添加另一个项目,notifyDataSetChanged()然后调用thengetView()被调用 8 次,位置开始从 0 开始并以 7 结尾,并且因为在该getView()方法中您正在从中获取数据,ArrayList那么它将自动返回插入列表中的新项目与前 8 个中的 7 个(7 而不是 8,因为最后一个项目去了一个位置)下来,所以它不再可见),并且ListView将使用这些项目重绘或其他任何内容。

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 videoat around 12:00 minutes to see the correct way to implement getView()

此外,重要的是要指定的是,如果您getView()正确实施,您最终将回收已显示的项目(对象)(而不是创建新项目)。12:00左右看这个视频,看看正确的实现方式getView()

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

我已经通过LogCat在每个方法中调用并跟踪正在发生的事情来解决所有这些问题。

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

希望这可以帮助刚刚开始了解ListViews 工作原理的人。

P.S. This examplealso helped me a lot to understand.

PS这个例子也帮助我理解了很多。

UPDATE

更新

Nowadays ListViewsare not really used anymore. Android came out with the RecyclerViewwhich does the recycling of the views for you, but knowing the basics of a ListViewhelps with understanding the RecyclerView.

现在ListViews已经不是真正使用了。安卓出来与RecyclerView它确实对你的意见回收,但我们知道的基本知识ListView与理解帮助RecyclerView

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

这里有一个链接供参考:https: //developer.android.com/guide/topics/ui/layout/recyclerview

回答by Dmitry Zaytsev

BaseAdaptercan be "observed" by other classes. When you're calling method of ListViewsetAdapter()it's calls registerDataSetObserverof adapter. So, adapter knows who are interested in new data.

BaseAdapter可以被其他类“观察”。当你调用ListViewsetAdapter()它的方法调用registerDataSetObserver适配器时。因此,适配器知道谁对新数据感兴趣。

You can check the source of BaseAdapterhere. It's pretty small.

你可以在BaseAdapter这里查看来源。它很小。

notifyDataSetChangedisavailable for you and you're basically shouldn't override it (because it's not doing anything special, so you can just reuse it in your own class).

notifyDataSetChanged供你和你根本不应该重写它(因为它没有做什么特别的东西,所以你可以重复使用它在自己的类)。

回答by Swayam

Suppose your ListViewdisplays some data stored in an ArrayList.

假设您ListView显示一些存储在ArrayList.

After you change the contents of the ArrayList, you need to tell the list that the source of the data had changed and it needs to redraw itself to show the new data.

更改 的内容后ArrayList,您需要告诉列表数据的来源已更改,并且需要重新绘制自己以显示新数据。

So, that is where notifyDatasetChanged()comes in. It tells the ListViewthat the data has been modified; and to show the new data, the ListViewmust be redrawn.

所以,这就是notifyDatasetChanged()进来的地方。它告诉ListView数据已被修改;并且要显示新数据,ListView必须重新绘制。

回答by Rupali Zambad

As you are extending BaseAdapterfor your own for creating a subclass, you will get notifyDataSetChanged()method as well.

当您BaseAdapter为自己扩展以创建子类时,您也将获得notifyDataSetChanged()方法。