我正在尝试理解ListView
概念及其工作原理,我正在尝试创建自己的扩展BaseAdapter
的适配器。例如,对于ArrayAdapter
,有一个notifyDataSetChanged()
方法应该在更新包含所有数据的数组列表后调用,以刷新ListView
。
但我正在创建自己的BaseAdapter
子类。那种方法对我来说不可用,或者是吗?我该如何实现这种方法?基本上,那个方法究竟做了什么,也许我会理解的。
如果ArrayAdapter
我猜测它会查看ListView
当前显示的位置,并检查它是否与ArrayList
更新后的位置相同?还是......
它说方法:
通知附加的观察者基础数据已经存在 已更改,任何反映数据集的视图都应自行刷新。
但它究竟是如何刷新自己的?
有人可以解释一下吗?
答案 0 :(得分:181)
我已经弄明白了。我无法理解适配器是如何开始的,以及它是如何知道从何处获取数据的。当我扩展BaseAdapter
类时,在该类的构造函数中,我初始化了我想在ListView
中看到的项列表。但我无法弄清楚如何使用这些值以及何时使用。
所以这就是事情!!! :强>
在BaseAdapter
中,有一些方法需要被覆盖。其中,有getCount()
。
创建ListView
时,会调用getCount()
。如果这返回一个不同于0的值(我返回了我之前在构造函数中初始化的ArrayList的大小),那么它会调用getView()
足够的次数来填充屏幕上的项目。 例如,我用20个项目初始化了ArrayList
。因为最初只有8个项目适合屏幕,getView()
被调用了8次,每次都要求我返回所需的位置(更确切地说,它想知道该行在列表中的行为如何具体位置,需要包含哪些数据)。如果我向下滚动列表,getView()
会一遍又一遍地被调用,直到我点击列表的末尾,在我的情况下是20项/行。
notifyDataSetChanged()
做的是......当被调用时,它会查看屏幕在调用时显示的内容(更准确地说是哪些行索引)并使用这些位置调用getView()
。
即如果你在列表中显示前8个项目(那些是屏幕上可见的项目),你在列表中的第2个和第3个项目之间添加另一个项目致电notifyDataSetChanged()
然后调用getView()
8次,位置从0开始,以7结尾,因为在getView()
方法中,您从ArrayList
获取数据它将自动返回插入列表中的新项目与前8个中的7个(7而不是8,因为最后一个项目向下移动一个位置,因此它不再可见),ListView
将重绘,或者其他什么,与这些项目。
另外,重要的是,如果您已正确实施getView()
,您将最终回收已显示的项目(对象)(而不是创建新项目)。请在12:00左右查看 this video ,以了解实施getView()
的正确方法
我已经通过在每个方法中调用LogCat
并跟踪发生的事情来解决所有问题。
希望这可以帮助刚刚开始理解ListView
工作方式的人。
P.S。 This example 也帮助我理解了很多。
答案 1 :(得分:13)
BaseAdapter
可以被其他类“观察”。当您调用ListView
setAdapter()
的方法时,它会调用适配器registerDataSetObserver
。因此,适配器知道谁对新数据感兴趣。
您可以查看BaseAdapter
here的来源。它很小。
notifyDataSetChanged
可供您使用,基本上不应该覆盖它(因为它没有做任何特殊的事情,因此您可以在自己的类中重复使用它。)< / p>
答案 2 :(得分:9)
假设您的ListView
显示存储在ArrayList
。
更改ArrayList
的内容后,您需要告诉列表数据来源已更改,并且需要重新绘制以显示新数据。
所以,这就是 notifyDatasetChanged()
的用武之地。它告诉ListView
数据已被修改;要显示新数据,必须重新绘制ListView
。
答案 3 :(得分:0)
当您为自己创建子类时扩展BaseAdapter
时,您也将获得notifyDataSetChanged()
方法。