Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓notifyDataSetChanged()方法和ListView是如何工作的?_Android_Android Listview_Android Adapterview - Fatal编程技术网

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

Android 安卓notifyDataSetChanged()方法和ListView是如何工作的?,android,android-listview,android-adapterview,Android,Android Listview,Android Adapterview,我试图理解ListView的概念及其工作原理,并尝试创建自己的适配器,扩展BaseAdapter。例如,对于ArrayAdapter,有一个notifyDataSetChanged()方法,在更新保存所有数据的数组列表后,应该调用该方法来刷新列表视图 但我正在创建自己的BaseAdapter子类。这种方法对我来说不可用,或者是吗?如何实现此方法?基本上,这个方法到底是做什么的,也许到时候我就会明白了 对于ArrayAdapter我猜它会查看ListView当前显示的位置,并检查更新后是否与Arr

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

但我正在创建自己的
BaseAdapter
子类。这种方法对我来说不可用,或者是吗?如何实现此方法?基本上,这个方法到底是做什么的,也许到时候我就会明白了

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

它说这种方法:

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

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


有人能解释一下吗?

假设您的
列表视图
显示了存储在
数组列表
中的一些数据

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


因此,
notifyDatasetChanged()
就是从这里开始的。它告诉
列表视图
数据已被修改;要显示新数据,必须重新绘制
列表视图。

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

您可以检查
BaseAdapter
的源代码。它很小


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

我已经找到了它。我无法理解适配器是如何启动的,它是如何知道从哪里获取数据的。当我扩展
BaseAdapter
类时,在该类的构造函数中,我初始化了我希望在
ListView
中看到的项目列表。但我不知道这些值将如何使用以及何时使用

事情是这样的!!!:

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

当创建
列表视图时,它调用
getCount()
。如果返回的值不同于0(我返回了我以前在构造函数中初始化过的ArrayList的大小),那么它调用
getView()
足够多的时间来填充屏幕上的项目例如,我用20项初始化了
ArrayList
。因为屏幕上最初只有8个项目,所以调用了8次
getView()
,每次都要求返回所需的位置(更准确地说,它想知道该行在该特定位置的列表中的外观,它需要包含哪些数据)。如果我向下滚动列表,
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
s工作原理的人

附言
也帮助我理解了很多东西

更新

如今,
listview
不再被真正使用。Android推出了
RecyclerView
,它为您回收视图,但了解
ListView
的基础知识有助于理解
RecyclerView


这里有一个供参考的链接:

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

这是我没有得到的。我在哪里告诉适配器我正在使用某个ArrayList存储数据?当我使用ArrayAdapter时,是的,当我将适配器链接到ListView时,我将引用发送到ArrayList,但是当我扩展BaseAdapter时呢?它怎么知道从我的ArrayList中获取值呢?那么