【问题标题】:What's the purpose of item-id's in Android ListView Adapter?Android ListView Adapter 中 item-id 的用途是什么?
【发布时间】:2011-02-24 03:32:27
【问题描述】:

(不是 ListView 特有的,而是 Adapter 特有的)。

当我继承 BaseAdapter 时,我一直在实现它:

    @Override
    public long getItemId(int position) {
        return position; 
    }

因为必须实现它。我看不出它有什么用,我只需要 getItem(position),不需要 getItemId(position)。

我想知道它是否有任何意义(对 Android SDK 或其他东西)?

【问题讨论】:

    标签: android listview position adapter


    【解决方案1】:

    想象一下这个结构:

    您有包含这样 3 条记录的 db 表注释:

    +----+--------------------------+
    | ID | Note Text                |
    +----+--------------------------+
    | 43 | Note text blah blah      |
    | 67 | Note text blah blah blah |
    | 85 | Last note                |
    +----+--------------------------+
    

    然后你实现一个适配器来提供这些数据。

    现在让我们看看在这种情况下的位置和项目id是什么

    position - 是加载数据集中记录位置的序数。例如,如果您使用 ORDER BY ID ASC 加载该表,则

    • ID 为 43 的记录的位置为 0
    • ID 为 67 的记录的位置为 1
    • ID 为 85 的记录的位置为 2

    itemId - 是记录的“主键”,您的实现可以返回这样的值

    • ID 为 43 的记录应该有 itemId 43,
    • ID 为 67 的记录应具有 itemId 67
    • ID 为 85 的记录应该有 itemId 85

    Android 标准适配器中的位置和 itemId

    ArrayAdapter / SimpleAdapter

    ArrayAdapterSimpleAdapter的位置和itemId是一样的:

    public long getItemId(int position) {
        return position; 
    }
    

    SimpleCursorAdapter(以及从 CursorAdapter 继承的所有类型)

    在 SimpleCursorAdapter 和 CursorAdapter 的所有后代中 itemId 是来自 _id 列的值:

    public long getItemId(int position) {
        if (mDataValid && mCursor != null) {
            if (mCursor.moveToPosition(position)) {
                return mCursor.getLong(mRowIDColumn);
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }
    

    【讨论】:

    • 几乎,但不完全...如果标题视图附加到列表,则 Array/SimpleAdapter 中的 position 和 itemId 不一样!在这些情况下,请使用行 ID 而不是位置,这样您就不需要从列表位置“计算”实际的项目行。
    • @dhaval 可能是因为这回答了 id 是什么而不是它们的用途。
    • @dhaval 是的,Simas 的评论是正确的。这个答案解释了 id 是什么,但没有解释为什么我必须实现 getItemId。有时我根本不使用 getItemId,因为 getItem 通常返回一个已经包含 id 的“item”。
    【解决方案2】:

    拥有稳定项 ID 的原因可能有很多。无法给出默认实现,因为它取决于存储在适配器中的对象类型。

    Android 会检查以确保项目 ID 仅在稳定时使用,即子类已正确覆盖 getItemIdBaseAdapter.hasStableIds 必须被覆盖才能返回 true。

    我遇到的几个原因:

    • AdapterView.OnItemClickListener的方法onItemClick(AdapterView<?> parent, View view, int position, long id)也发送long id

    • getCheckedItemIds方法The result is only valid if the choice mode has not been set to CHOICE_MODE_NONE and the adapter has stable IDs.

    回复“因为必须实现”:您不必必须如果您不使用这些功能,则没有必要。但如果你这样做了,也不要忘记覆盖boolean hasStableIds()

    【讨论】:

      【解决方案3】:

      正如@Reno 所写,它允许您将视图中的行映射到数据集元素。

      这样做的目的之一是允许 ListViews 跟踪选择了哪个项目,即使列表中的位置已更改或基础数据已更新。

      【讨论】:

        【解决方案4】:

        如果您改为子类化 ArrayAdapter,则可能不必实现该方法。

        大多数情况下,我发现该方法可用于确定在 onClick 事件期间单击了哪一行,并将该 ID 用作传递给下一个活动的 Intent extras 的一部分。

        【讨论】:

          【解决方案5】:

          是的,它是一个abstract function,由 android 调用以将适配器数据集的行 ID 映射到您的列表位置。

          欢迎挖deeper

          【讨论】:

            猜你喜欢
            • 2019-06-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-23
            • 2017-03-01
            • 1970-01-01
            相关资源
            最近更新 更多