ListView selection remains persistent after exiting choice mode

后端 未结 11 813
青春惊慌失措
青春惊慌失措 2020-11-29 01:45

I have a ListView subclass that I allow selections on when the context action bar (CAB) is active. The CAB is set as a callback to the onItemLongClick event:

相关标签:
11条回答
  • 2020-11-29 02:02

    Looking at the ListView sourcecode, the only way to work around this is to set the ListView to CHOICE_MODE_NONE, then re-assign the ListAdapter (which clears the internal selection list regardless of choice mode)

    i.e. in a ListFragment/ListActivity

    getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
    getListView().setAdapter(getListAdapter())
    
    0 讨论(0)
  • 2020-11-29 02:04

    Is not a bug. That behavior is required to support multiple HID for Android. So to show the selection state you only need set the choice mode of the listview and a background to support the selected state for the "list item layout", like:

    android:background="?android:attr/activatedBackgroundIndicator"

    FYI: http://android-developers.blogspot.mx/2008/12/touch-mode.html

    0 讨论(0)
  • 2020-11-29 02:05

    I was having this issue in API Level 17 and solved it by doing:

    listView.clearChoices();
    listView.invalidateViews();
    
    0 讨论(0)
  • 2020-11-29 02:07

    I have found that the only two methods that work here (API 19) are:

    • Resetting the list adapter, which is undesirable because it goes back to the top of the list;
    • Setting the choice mode to CHOICE_MODE_NONE in a new Runnable

    If the choice mode is changed without using listView.post(new Runnable()), it doesn't work. Can anyone explain to me why this is?

    Apologies for not commenting; I have no reputation.

    Thanks.

    0 讨论(0)
  • 2020-11-29 02:07

    Not sure if this is too late just wanted to share. I created an intent to the same page so that once the clicked data is captured it recreates a fresh page without any clicked persistence.

    0 讨论(0)
  • 2020-11-29 02:09

    I had tried all the approaches discussed above but none of them work for me. Finally, I decide to apply the following workaround. The key idea is that,

    During multimode, instead of reusing the "cached" view, we will create a completely new view. Not efficient, but at least "partially" solve my problem.

    Here is the code of my customized 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);
        }
    

    Also, I feel safer to have the following code in ActionMode.Callback, although I'm not sure how much it helps.

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            MyFragment.this.myArrayAdapter.setMultimode(false);
    
            // http://stackoverflow.com/questions/9754170/listview-selection-remains-persistent-after-exiting-choice-mode
            // 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;
        }
    

    Side Note

    Using MultiChoiceModeListener couple with CHOICE_MODE_MULTIPLE_MODAL will make this bug gone. However, for device below API level 11 will not able to use this solution.

    0 讨论(0)
提交回复
热议问题