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

And*_*dan 59 android android-listview android-adapterview

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

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

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

它说的方法:

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

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

有人可以解释一下吗?

And*_*dan 185

我已经明白了.我无法理解适配器是如何启动的,以及它是如何知道从何处获取数据的.当我扩展BaseAdapter类时,在该类的构造函数中,我初始化了我想要在其中看到的项列表ListView.但我无法弄清楚这些值将如何使用以及何时使用.

所以这就是事!:

BaseAdapter某些方法中需要重写.其中有getCount().

ListView创建和诸如此类的东西时,它会调用getCount().如果这返回一个不同于0的值(我返回了我之前在构造函数中初始化的ArrayList的大小),那么它会调用getView()足够的时间来填充屏幕上的项目.例如,我初始化了ArrayList20个项目.因为最初只有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左右观看此视频,了解正确的实施方式getView()

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

希望这能帮助刚刚开始理解ListView工作方式的人.

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

  • 很好的解释:),希望我能给出超过1票. (7认同)
  • 这是我遇到过的最好的解释之一!超级东西! (7认同)
  • 嗯,这是一个很好的解释.但我们认为您知道ListView的工作原理. (5认同)
  • *因为屏幕上最初只有8个项目,所以getView()被调用了8次*.这并不总是正确的,因为适配器可以调用一些额外的`getView来进行测量. (3认同)

Dmi*_*sev 13

BaseAdapter可以被其他班级"观察".当你调用ListView setAdapter()它的方法调用registerDataSetObserver适配器时.因此,适配器知道谁对新数据感兴趣.

你可以查看BaseAdapter 这里的来源.它很小.

notifyDataSetChanged 可用的,你基本上不应该覆盖它(因为它没有做任何特殊的事情,所以你可以在你自己的类中重复使用它).


Swa*_*yam 9

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

更改内容后ArrayList,您需要告诉列表数据源已更改,并且需要重绘自身以显示新数据.

所以,这就是它的notifyDatasetChanged()用武之地.它告诉ListView我们数据已被修改; 要显示新数据,ListView必须重新绘制.