Android

ListView selection remains persistent after exiting choice mode

Выбор ListView остается постоянным после выхода из режима выбора

У меня есть подкласс ListView, в котором я разрешаю выбор, когда активна панель контекстных действий (CAB). CAB устанавливается как обратный вызов для onItemLongClick события:

public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(context_menu, menu);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
return true;
}

Это нормально, и ListView работает как ожидалось, при этом выбранный в данный момент элемент остается выделенным при касании.

Когда я закрываю CAB, я хочу, чтобы ListView вернулся в обычный режим (т. Е. Сенсорный режим). Проблема в том, что последний выбранный элемент остается выделенным неопределенно долго, независимо от того, какими методами я пытаюсь его очистить:

public void onDestroyActionMode(ActionMode mode) {
//Unselect any rows
ListView lv = getListView();
lv.clearChoices(); // Has no effect
lv.setChoiceMode(ListView.CHOICE_MODE_NONE); // Has no effect on the highlighted item
lv.setFocusable(false); // Has no effect
lv.setSelection(0); // Has no effect
mActionMode = null;
}

Есть предложения?

Переведено автоматически
Ответ 1

Основная причина проблемы заключается в том, что как только ListView режим выбора переключается в CHOICE_MODE_NONE, фреймворк оптимизирует операцию очистки, поскольку он больше не поддерживает "выбор". Я немного улучшил вышеупомянутые обходные пути, очистив состояние выбора вручную, а затем установив режим отложенным образом, чтобы у фреймворка была очередь очистить состояние перед переключением режима в CHOICE_MODE_NONE.

final ListView lv = getListView();
lv.clearChoices();
for (int i = 0; i < lv.getCount(); i++)
lv.setItemChecked(i, false);
lv.post(new Runnable() {
@Override
public void run() {
lv.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
Ответ 2

Я столкнулся с той же проблемой, и поскольку запрос макета для меня тоже не решает проблему, я реализовал небольшой хак, который работает у меня. Возможно, это та же проблема, потому что я переключаюсь между CHOICE_MODE_SINGLE и CHOICE_MODE_NONE.

Когда режим действия заканчивается, я вызываю этот фрагмент кода. clearChoices проверяет, что все элементы больше не проверяются (внутренне). Итерация по представлениям гарантирует, что все видимые в данный момент представления сброшены и больше не проверяются.

mListView.clearChoices();

for (int i = 0; i < mListView.getChildCount(); i++) {
((Checkable) mListView.getChildAt(i)).setChecked(false);
}

mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
Ответ 3

Глядя на исходный код ListView, единственный способ обойти это - установить для ListView значение CHOICE_MODE_NONE , затем повторно назначить ListAdapter (который очищает внутренний список выбора независимо от режима выбора)

т.е. в ListFragment / ListActivity

getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
getListView().setAdapter(getListAdapter())
Ответ 4

У меня возникла эта проблема в API Level 17 и я решил ее, выполнив:

listView.clearChoices();
listView.invalidateViews();
java android android-listview