【发布时间】:2013-08-13 19:21:18
【问题描述】:
我正在实现 ExpandableListView 的 ListAdapter,在工作时我发现我需要覆盖函数 boolean hasStableIds()。 谁能解释一下稳定ID的含义是什么?我什么时候需要这个?
【问题讨论】:
我正在实现 ExpandableListView 的 ListAdapter,在工作时我发现我需要覆盖函数 boolean hasStableIds()。 谁能解释一下稳定ID的含义是什么?我什么时候需要这个?
【问题讨论】:
稳定的 ID 允许 ListView 针对 notifyDataSetChanged 调用之间项目保持不变的情况进行优化。它引用的 ID 是从 getItemId 返回的 ID。
没有它,ListView 必须重新创建所有 Views,因为它无法知道数据更改之间的项目 ID 是否相同(例如,如果 ID 只是数据中的索引,它必须重新创建一切)。有了它,它可以避免重新创建保留其项目 ID 的Views。
【讨论】:
id 保证引用特定的唯一对象时,它应该返回true,这样id 的变化表示对象已更改并且id 保持不变意味着它不是某个返回相同id 的新对象,在这种情况下,必须更新视图并且需要方法返回false。
RecycledViewPool 中,应该被回收。对我而言,稳定 ID 的优势在于您无需再次绑定它们。还是我错过了什么?
如果hasStableIds() 返回false,那么您每次调用notifyDataSetChanged() 时,您的适配器都会查看getItemId 的返回值并最终调用getView(int position, View convertView, ViewGroup parent)。如果hasStableIds() 返回true,则只有在他们的 id 发生变化时才会这样做。
使用这种技术,您可以轻松地只更新 ListView 中的一项
如果你正确实现getItemId,那么它可能会非常有用。
例子:
你有一个专辑列表:
class Album{
String coverUrl;
String title;
}
然后你像这样实现getItemId:
@Override
public long getItemId(int position){
Album album = mListOfAlbums.get(position);
return (album.coverUrl + album.title).hashCode();
}
现在您的项目 ID 取决于 coverUrl 和 title 字段的值,如果您更改它们并在适配器上调用 notifyDataSetChanged(),那么适配器将调用 getItemId () 方法,并且只更新那些 id 已经改变的项目。
如果在您的 getView() 中执行一些“繁重”操作,这将非常有用。
【讨论】:
hashCode() 为 2 个不同的字符串返回相同的数字(即您有哈希码冲突)会发生什么?概括地说,如果您的 getItemId(int position) 返回的 ID 不是唯一的。它如何影响ListView?