Какова цель идентификаторов элементов в 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.
Несколько причин, с которыми я столкнулся:
Метод 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()
также.
Представьте себе эту структуру:
У вас есть дБ таблицы 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 для сопоставления идентификатора строки набора данных адаптера с вашей позицией в списке.
Вы можете копать глубже