Какова цель идентификаторов элементов в Android ListView Adapter?

(Не только для ListView, но и для Adapter).

Я продолжаю реализовывать это, когда я создаю подкласс BaseAdapter:

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

Потому что должны это реализовать. Я не вижу никакого смысла в этом, мне нужен только getItem (position), а не getItemId (position).

Интересно, имеет ли это какое-то значение (для Android SDK или еще чего-нибудь)?

5 ответов

Решение

Вероятно, есть много причин иметь стабильные идентификаторы предметов. Реализация по умолчанию не может быть предоставлена, поскольку она зависит от типа объекта, сохраняемого в адаптере.

Android имеет проверку, чтобы убедиться, что идентификаторы элементов используются только тогда, когда они стабильны, то есть подкласс правильно переопределен getItemId; BaseAdapter.hasStableIds должен быть переопределен, чтобы возвращать true.

Несколько причин, с которыми я столкнулся:

Ответьте "Потому что нужно это реализовать": вам не нужно, если вы не используете функции, в этом нет необходимости. Но если вы это сделаете, не забудьте переопределить boolean hasStableIds() также.

Представьте себе эту структуру:

У вас есть дБ таблицы Notes с такими 3 записями:

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

и вы реализуете адаптер для обслуживания этих данных.

Теперь давайте посмотрим, что позиция и идентификатор элемента в таком случае

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

position и itemId в стандартных адаптерах Android

ArrayAdapter / SimpleAdapter

В ArrayAdapter а также SimpleAdapter position и 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;
    }
}

Как пишет @Reno, он позволяет отображать строки в представлении в элементы набора данных.

Одна из целей этого состоит в том, чтобы позволить ListViews отслеживать, какой элемент выбран, даже если позиции в списке изменены или базовые данные обновлены.

Если вместо этого вы создадите подкласс ArrayAdapter, вам может не понадобиться реализовывать этот метод.

В основном я нахожу этот метод полезным, чтобы определить, какая строка была нажата во время событий onClick, и использовать этот идентификатор как часть дополнительных функций Intent, переданных следующему действию.

Да, это абстрактная функция, которая вызывается android для сопоставления идентификатора строки набора данных адаптера с вашей позицией в списке.

Вы можете копать глубже

Другие вопросы по тегам