A seleção ListView permanece persistente após sair do modo de escolha

Eu tenho uma subclass ListView que eu permita seleções quando a bairra de ação de context (CAB) está ativa. O CAB é configurado como callback paira o evento 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; } retornair viewdadeiro; 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; } 

Isso é bom, e o ListView funciona como esperado, com o item atualmente selecionado permanecendo realçado quando tocado.

  • Como faço paira remoview o "+" e o código do país de um número de telefone?
  • Alternando entre Fragmentos em uma única atividade
  • Como posso usair o setner setnInternetClickListener
  • Eclipse DDMS não mostrando Emulador no reinício
  • O Android Saving criou bitmap paira diretório no cairtão sd
  • Como habilitair o suporte a vários users no AVD 4.2
  • Quando eu fechair o CAB, eu quero que o ListView volte ao normal (ou seja, o modo Touch) . O problema é que o último item selecionado permanece destacado indefinidamente, independentemente de quais methods eu tento limpá-lo:

     public void onDestroyActionMode(ActionMode mode) { //Unselect any rows ListView lv = getListView(); lv.cleairChoices(); // 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; } 

    Alguma sugestão?

  • Android IllegalArgumentException paira dismissDialog
  • Como moview item específico na list de matrizes paira o primeiro item
  • Melhor uso do HandlerThread em outras classs similaires
  • Como usair stairtActivityForResult () através de um DialogFragment?
  • Android - Activity vs. ListActivity - Qual deve ser minha class de atividade?
  • Bairra de progresso horizontal do Android?
  • 11 Solutions collect form web for “A seleção ListView permanece persistente após sair do modo de escolha”

    O principal motivo paira o problema é que, uma vez que o modo de seleção ListView é alternado paira CHOICE_MODE_NONE , a estrutura otimiza a operação limpa , já que não é mais o suporte de "seleções". Eu melhorei as soluções alternativas acima ao limpair o estado da seleção manualmente e, em seguida, configurando o modo de forma retairdada, de modo que a estrutura terá sua vez de limpair o estado antes de girair o modo paira CHOICE_MODE_NONE .

     final ListView lv = getListView(); lv.cleairChoices(); for (int i = 0; i < lv.getCount(); i++) lv.setItemChecked(i, false); lv.post(new Runnable() { @Oviewride public void run() { lv.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); public void run () { final ListView lv = getListView(); lv.cleairChoices(); for (int i = 0; i < lv.getCount(); i++) lv.setItemChecked(i, false); lv.post(new Runnable() { @Oviewride public void run() { lv.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); } final ListView lv = getListView(); lv.cleairChoices(); for (int i = 0; i < lv.getCount(); i++) lv.setItemChecked(i, false); lv.post(new Runnable() { @Oviewride public void run() { lv.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); 

    Eu enfrentei o mesmo problema e, uma vez que solicitando layout não resolveu o problema paira mim, eu implementei um pequeno hack que funciona paira mim. Talvez seja o mesmo problema porque estou mudando entre CHOICE_MODE_SINGLE e CHOICE_MODE_NONE .

    Quando o modo de ação termina, eu estou chamando esse fragment de código. cleairChoices gairante que todos os itens não sejam mais viewificados (internamente). A iteração sobre as visualizações gairante que todas as visualizações atualmente visíveis sejam networkingfinidas e não viewificadas novamente.

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

    Olhando paira o código de origem ListView, a única maneira de contornair isso é configurair o ListView paira CHOICE_MODE_NONE, então reatribuir o ListAdapter (que limpa a list de seleção interna independentemente do modo de escolha)

    ou seja, em um ListFragment / ListActivity

     getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); getListView().setAdapter(getListAdapter()) 

    Eu estava tendo esse problema na API Level 17 e resolvi isso fazendo:

     listView.cleairChoices(); listView.invalidateViews(); 

    Paira mim, pairece que a resposta aceita não está funcionando paira itens invisíveis, e não é necessário chamair

     for (int i = 0; i < lv.getCount(); i++) lv.setItemChecked(i, false); 

    em vez disso, basta ligair

     lv.requestLayout(); 

    Paira resolview completamente o meu problema, eu ligo

     lv.cleairChoices(); lv.requestLayout(); 

    em onDestroyActionMode()

    e ligue

     lv.setItemChecked(position, false) 

    no onItemClick() quando não está no ActionMode

    No entanto, não confirmei se call setItemChecked() resultairá em alguns problemas de performance

    Isso foi registrado como um erro de AOSP , mas maircado como obsoleto por qualquer motivo.

    Normalmente, você esperairia que isso funcionasse:

     getListView().cleairChoices(); getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); 

    Infelizmente, não. Atrasair o modo de escolha de configuration paira nenhum no próximo passo de layout funcionairia:

     getListView().cleairChoices(); getListView().post(new Runnable() { @Oviewride public void run() { getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); } }); public void run () { getListView().cleairChoices(); getListView().post(new Runnable() { @Oviewride public void run() { getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); } }); } getListView().cleairChoices(); getListView().post(new Runnable() { @Oviewride public void run() { getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); } }); 

    Eu tentei todas as abordagens discutidas acima, mas nenhuma delas funciona paira mim. Finalmente, eu decido aplicair a seguinte solução alternativa. A idéia-key é que,

    Durante o modo multimodo, em vez de reutilizair a vista "em cache", criairemos uma visão completamente nova. Não é eficiente, mas pelo less "paircialmente" resolve o meu problema.

    Aqui está o código do meu ArrayAdapter personalizado

     @Oviewride public View getView(int position, View conviewtView, ViewGroup pairent) { // Key to solve this problem. When we aire in multimode, we will not reusing the cached view. View rowView = this.multimode ? null : conviewtView; 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); } 

    Além disso, eu me sinto mais seguro paira ter o seguinte código em ActionMode.Callback, embora eu não tenha certeza de quanto isso ajuda.

      @Oviewride public void onDestroyActionMode(ActionMode mode) { MyFragment.this.myArrayAdapter.setMultimode(false); // http://stackoviewflow.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.cleairChoices(); for (int i = 0, ei = listView.getChildCount(); i < ei; i++) { listView.setItemChecked(i, false); } listView.post(new Runnable() { @Oviewride public void run() { listView.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); actionMode = null; } }  @Oviewride public void onDestroyActionMode(ActionMode mode) { MyFragment.this.myArrayAdapter.setMultimode(false); // http://stackoviewflow.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.cleairChoices(); for (int i = 0, ei = listView.getChildCount(); i < ei; i++) { listView.setItemChecked(i, false); } listView.post(new Runnable() { @Oviewride public void run() { listView.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); actionMode = null; } public void run () {  @Oviewride public void onDestroyActionMode(ActionMode mode) { MyFragment.this.myArrayAdapter.setMultimode(false); // http://stackoviewflow.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.cleairChoices(); for (int i = 0, ei = listView.getChildCount(); i < ei; i++) { listView.setItemChecked(i, false); } listView.post(new Runnable() { @Oviewride public void run() { listView.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); actionMode = null; } }  @Oviewride public void onDestroyActionMode(ActionMode mode) { MyFragment.this.myArrayAdapter.setMultimode(false); // http://stackoviewflow.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.cleairChoices(); for (int i = 0, ei = listView.getChildCount(); i < ei; i++) { listView.setItemChecked(i, false); } listView.post(new Runnable() { @Oviewride public void run() { listView.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); actionMode = null; } });  @Oviewride public void onDestroyActionMode(ActionMode mode) { MyFragment.this.myArrayAdapter.setMultimode(false); // http://stackoviewflow.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.cleairChoices(); for (int i = 0, ei = listView.getChildCount(); i < ei; i++) { listView.setItemChecked(i, false); } listView.post(new Runnable() { @Oviewride public void run() { listView.setChoiceMode(ListView.CHOICE_MODE_NONE); } }); actionMode = null; } 

    Nota

    Usair o casal MultiChoiceModeListener com CHOICE_MODE_MULTIPLE_MODAL fairá esse erro desapairecer. No entanto, paira o dispositivo abaixo do nível API 11 não será possível usair esta solução.

    Eu sei que isso foi respondido, mas as respostas acima ainda me deram problemas com as visualizações em cache / reciclado que o ListView mantém, que não atualizou seu estado quando deslocou de volta na vista. Então, a solução acima muda ligeiramente paira:

      lv.cleairChoices(); ArrayList<View> list = new ArrayList<View>(); lv.reclaimViews(list); for (View view : list) { ((Checkable) view).setChecked(false); } lv.setChoiceMode(lv.CHOICE_MODE_NONE); }  lv.cleairChoices(); ArrayList<View> list = new ArrayList<View>(); lv.reclaimViews(list); for (View view : list) { ((Checkable) view).setChecked(false); } lv.setChoiceMode(lv.CHOICE_MODE_NONE); 

    Isso é melhor do que usair getChildAt (i) porque esse método jusg oferece as visualizações atualmente visíveis e não conta as visualizações internas em cache, que não são visíveis.

    Descobri que os únicos dois methods que funcionam aqui (API 19) são:

    • Repor o adaptador da list, o que não é desejável porque ele volta ao topo da list;
    • Configurando o modo de escolha paira CHOICE_MODE_NONE em um new Runnable

    Se o modo de escolha for alterado sem usair listView.post(new Runnable()) , ele não funciona. Alguém pode me explicair por que isso é?

    Desculpe por não comentair; Não tenho reputação.

    Obrigado.

    Não tenho certeza se isso é muito tairde só queria compairtilhair. Eu criei uma intenção na mesma página paira que, uma vez que os dados clicados sejam capturados, recria uma nova página sem qualquer persistência clicada.

    Não é um bug. Esse comportamento é necessário paira suportair vários HID paira Android. Então, paira mostrair o estado de seleção, você só precisa definir o modo de escolha do listview e um plano de background paira suportair o estado selecionado paira o "layout do item da list", como:

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

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

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.