63

我正在尝试理解这个ListView概念以及它是如何工作的,并且我正在尝试创建自己的扩展BaseAdapter. 例如ArrayAdapternotifyDataSetChanged()在更新包含所有数据的数组列表后应该调用该方法,以刷新ListView.

但我正在创建自己的BaseAdapter. 我无法使用该方法,或者是吗?我如何实现这个方法?基本上,那个方法到底是做什么的,也许我会明白。

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

它说该方法:

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

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

有人可以解释一下吗?

4

4 回答 4

193

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

所以这就是事情!:

其中BaseAdapter有一些方法需要被覆盖。其中,有getCount()

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

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

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

此外,需要说明的是,如果您已getView()正确实施,您最终将回收已显示的项目(对象)(而不是创建新项目)。在 12:00 左右观看此视频以了解正确的实施方式getView()

LogCat通过在每个方法中调用并跟踪正在发生的事情,我已经弄清楚了这一切。

希望这对刚刚开始了解ListViews 工作原理的人有所帮助。

PS这个例子对我理解也有很大帮助。

更新

现在ListViews已经不再使用了。Android 推出了RecyclerViewwhich 会为您回收视图,但了解 a 的基础知识ListView有助于理解RecyclerView.

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

于 2012-09-02T08:34:10.317 回答
13

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

您可以查看BaseAdapter 此处的来源。它很小。

notifyDataSetChanged 可供您使用,并且您基本上不应该覆盖它(因为它没有做任何特别的事情,所以您可以在自己的课程中重用它)

于 2012-09-01T17:52:49.953 回答
10

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

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

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

于 2012-09-01T17:33:10.053 回答
0

当您BaseAdapter为自己的子类进行扩展时,您也将获得notifyDataSetChanged()方法。

于 2016-12-08T09:28:05.770 回答