【问题标题】:Android - what is the meaning of StableIDs?Android - StableID 的含义是什么?
【发布时间】:2013-08-13 19:21:18
【问题描述】:

我正在实现 ExpandableListView 的 ListAdapter,在工作时我发现我需要覆盖函数 boolean hasStableIds()。 谁能解释一下稳定ID的含义是什么?我什么时候需要这个?

【问题讨论】:

    标签: android listview


    【解决方案1】:

    稳定的 ID 允许 ListView 针对 notifyDataSetChanged 调用之间项目保持不变的情况进行优化。它引用的 ID 是从 getItemId 返回的 ID。

    没有它,ListView 必须重新创建所有 Views,因为它无法知道数据更改之间的项目 ID 是否相同(例如,如果 ID 只是数据中的索引,它必须重新创建一切)。有了它,它可以避免重新创建保留其项目 ID 的Views。

    【讨论】:

    • 例如如果 ID 只是数据中的索引,它必须重新创建所有内容 这不应该与事实相反吗?我的意思是,如果 id 只是索引,那么它总是稳定的,因为它永远不会改变。索引 n 处的元素将始终返回 n 的 id,因此永远不会更改。 @DanyloVolokh 给出的解释支持我的逻辑
    • 这就是你使用hasStableIds和从getItemId返回的数组索引的情况,是的。我承认,措辞不是很好。欢迎编辑:)
    • 为了清楚起见,根据文档here,当id 保证引用特定的唯一对象时,它应该返回true,这样id 的变化表示对象已更改并且id 保持不变意味着它不是某个返回相同id 的新对象,在这种情况下,必须更新视图并且需要方法返回false
    • 没有它,ListView 必须重新创建所有 Views 相反,Views 在RecycledViewPool 中,应该被回收。对我而言,稳定 ID 的优势在于您无需再次绑定它们。还是我错过了什么?
    【解决方案2】:

    如果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 取决于 coverUrltitle 字段的值,如果您更改它们并在适配器上调用 notifyDataSetChanged(),那么适配器将调用 getItemId () 方法,并且只更新那些 id 已经改变的项目。

    如果在您的 getView() 中执行一些“繁重”操作,这将非常有用。

    【讨论】:

    • 我想,你的意思是“如果 hasStableIds() 返回 true”,对吧?
    • 不,我的意思是“假”。当 id 不稳定时。 (可变)
    • 关于您的示例,如果 hashCode() 为 2 个不同的字符串返回相同的数字(即您有哈希码冲突)会发生什么?概括地说,如果您的 getItemId(int position) 返回的 ID 不是唯一的。它如何影响ListView
    • -1。这个答案是完全错误的。 RecyclerView 只能在item 有stable id 并且你调用setHasStableIds(true) 的情况下才能避免不必要的工作。示例代码在任何情况下都不会像作者所说的那样工作。 hasStableIds() 询问关于项目 identities 的问题,而不是关于项目 values 的问题。如果 hasStableIds() 返回 false,则适配器必须在每次更新时重新创建所有视图,因为它不能假定具有相同 ID 的列表项对应于相同的数据。
    • 除了@ClementCherlin 的注释之外,hashCode 方法作为标识符是不可靠的。请记住,哈希并不能保证唯一性,而是无法找到冲突。冲突在哈希函数中非常常见,对于大型数据集,它们可能会导致提供的数据与显示的数据不一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2014-10-13
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多