Выбор ListView остается постоянным после выхода из режима выбора - PullRequest
41 голосов
/ 18 марта 2012

У меня есть подкласс 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;
}

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

Ответы [ 11 ]

0 голосов
/ 22 апреля 2013

Я перепробовал все подходы, описанные выше, но ни один из них не работает для меня.Наконец, я решил применить следующий обходной путь.Основная идея заключается в том, что

Во время многомодового режима вместо повторного использования «кэшированного» представления мы создадим совершенно новое представление.Не эффективно, но, по крайней мере, «частично» решает мою проблему.

Вот код моей настройки ArrayAdapter

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Key to solve this problem. When we are in multimode, we will not reusing the cached view.
    View rowView = this.multimode ? null : convertView;

    if (rowView == null) {
        LayoutInflater inflater = activity.getLayoutInflater();
        rowView = inflater.inflate(R.layout.watchlist_row_layout, null);
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.textView0 = (TextView) rowView.findViewById(R.id.text_view_0);
        viewHolder.textView1 = (TextView) rowView.findViewById(R.id.text_view_1);
        viewHolder.textView2 = (TextView) rowView.findViewById(R.id.text_view_2);
        rowView.setTag(viewHolder);
    }

Кроме того, я чувствую себя более безопасным, чтобы иметь следующеекод в ActionMode.Callback, хотя я не уверен, насколько это поможет.

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        MyFragment.this.myArrayAdapter.setMultimode(false);

        // /6426381/vybor-listview-ostaetsya-postoyannym-posle-vyhoda-iz-rezhima-vybora
        // Using View.post is the key to solve the problem.
        final ListView listView = MyFragment.this.getListView();
        listView.clearChoices();
        for (int i = 0, ei = listView.getChildCount(); i < ei; i++) {
            listView.setItemChecked(i, false);
        }
        listView.post(new Runnable() {
            @Override
            public void run() {
                listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
            }
        });
        actionMode = null;
    }

Примечание для стороны

Использование пары MultiChoiceModeListener с CHOICE_MODE_MULTIPLE_MODAL устранит эту ошибку.Однако для устройства ниже API уровня 11 не удастся использовать это решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...