Android系统。 notifyDataSetChanged()方法和ListViews如何工作?

时间:2012-09-01 17:21:18

标签: android android-listview android-adapterview

我正在尝试理解ListView概念及其工作原理,我正在尝试创建自己的扩展BaseAdapter的适配器。例如,对于ArrayAdapter,有一个notifyDataSetChanged()方法应该在更新包含所有数据的数组列表后调用,以刷新ListView

但我正在创建自己的BaseAdapter子类。那种方法对我来说不可用,或者是吗?我该如何实现这种方法?基本上,那个方法究竟做了什么,也许我会理解的。

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

它说方法:

  

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

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

有人可以解释一下吗?

4 个答案:

答案 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()方法。