Подтвердить что ты не робот

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

(Не относится к ListView, но к адаптеру).

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

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

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

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

4b9b3361

Ответ 1

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

Android имеет проверку, чтобы убедиться, что идентификаторы элементов используются только тогда, когда они установлены, т.е. подкласс правильно переопределен getItemId; BaseAdapter.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().

Ответ 2

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

У вас есть таблица db с такими 3 записями:

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

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

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

position - порядковый номер позиции записи в загруженном наборе данных. Например, если вы загрузите эту таблицу с помощью ORDER BY ID ASC, то

  • запись с идентификатором 43 будет иметь позицию 0,
  • запись с идентификатором 67 будет иметь позицию 1,
  • запись с идентификатором 85 будет иметь позицию 2

itemId - это "первичный ключ" записи, и ваша реализация может вернуть такие значения

  • запись с идентификатором 43 должна иметь itemId 43,
  • запись с идентификатором 67 должна иметь itemId 67,
  • запись с идентификатором 85 должна иметь itemId 85

позиция и itemId в стандартных адаптерах Android

ArrayAdapter/SimpleAdapter

В ArrayAdapter и SimpleAdapter позиция и 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;
    }
}

Ответ 3

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

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

Ответ 4

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

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