La selección de ListView permanece persistente después de salir del modo de elección
Tengo una subclase ListView que permito selecciones cuando la barra de acción de contexto (CAB) está activa. La CAB se establece como una devolución de llamada al 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;
}
Esto está bien, y la vista de lista funciona como se espera, con el elemento seleccionado actualmente permanece resaltado cuando se toca.
Cuando cierro la CABINA, quiero que la vista de lista vuelva a la normalidad (es decir, al modo Táctil). El problema es que el último elemento seleccionado permanece resaltado indefinidamente, independientemente de los métodos Trato de aclararlo:
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;
}
Alguna sugerencia?
11 answers
La razón principal del problema es que una vez que el modo de selección ListView
se cambia a CHOICE_MODE_NONE
, el marco optimiza la operación clear ya que ya no admite 'selecciones'. He mejorado un poco las soluciones anteriores borrando el estado de selección manualmente y luego configurando el modo de manera retardada para que el marco tenga su turno para borrar el estado antes de convertir el modo a 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);
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-02 09:01:54
Me enfrenté al mismo problema y ya que solicitar el diseño no resuelve el problema para mí tampoco implementé un pequeño truco que funciona para mí. Tal vez este es el mismo problema porque estoy cambiando entre CHOICE_MODE_SINGLE
y CHOICE_MODE_NONE
.
Cuando el modo de acción termina, estoy llamando a este fragmento de código. clearChoices
se asegura de que todos los elementos ya no se comprueben (internamente). La iteración sobre las vistas garantiza que todas las vistas actualmente visibles se restablezcan y ya no se comprueben.
mListView.clearChoices();
for (int i = 0; i < mListView.getChildCount(); i++) {
((Checkable) mListView.getChildAt(i)).setChecked(false);
}
mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-10 21:47:12
Mirando el código fuente de ListView, la única manera de solucionar esto es establecer la ListView en CHOICE_MODE_NONE, luego reasignar el ListAdapter (que borra la lista de selección interna independientemente del modo de elección)
Es decir, en un ListFragment/ListActivity
getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
getListView().setAdapter(getListAdapter())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-21 14:03:01
Estaba teniendo este problema en API Level 17
y lo resolví haciendo:
listView.clearChoices();
listView.invalidateViews();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-15 16:10:47
Para mí, parece que la respuesta aceptada no funciona para elementos invisibles, y no es necesario llamar
for (int i = 0; i < lv.getCount(); i++)
lv.setItemChecked(i, false);
En su lugar, simplemente llame a
lv.requestLayout();
Para resolver completamente mi problema, llamo
lv.clearChoices();
lv.requestLayout();
En onDestroyActionMode()
Y llamar
lv.setItemChecked(position, false)
In onItemClick()
when it's not in ActionMode
Sin embargo, no confirmé si la llamada setItemChecked()
dará lugar a algunos problemas de rendimiento
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 03:04:24
Esto ha sido registrado como un bug de AOSP, pero marcado como obsoleto por cualquier razón.
Normalmente esperarías que esto funcionara:
getListView().clearChoices();
getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
Desafortunadamente no lo hace. Diferir el modo de elección de configuración a ninguno en el siguiente pase de diseño funcionaría:
getListView().clearChoices();
getListView().post(new Runnable() {
@Override
public void run() {
getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-02 08:20:09
Había probado todos los enfoques discutidos anteriormente, pero ninguno de ellos funciona para mí. Finalmente, decido aplicar la siguiente solución. La idea clave es que,
Durante multimodo, en lugar de reutilizar la vista "cached", crearemos una vista completamente nueva. No eficiente, pero al menos "parcialmente" resolver mi problema.
Aquí está el código de mi personalizado 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);
}
Además, me siento más seguro de tener el siguiente código en ActionMode.Callback, aunque no estoy seguro de cómo ayuda mucho.
@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;
}
Nota al margen
Usando el par MultiChoiceModeListener con CHOICE_MODE_MULTIPLE_MODAL hará que este error desaparezca. Sin embargo, para el dispositivo por debajo del nivel de API 11 no podrá utilizar esta solución.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-25 07:24:17
Sé que esto ha sido respondido, pero las respuestas anteriores todavía me dieron problemas con las vistas en caché/recicladas que mantiene ListView, que no actualizaron su estado cuando se volvió a ver. Por lo tanto, la solución anterior cambia ligeramente a:
lv.clearChoices();
ArrayList<View> list = new ArrayList<View>();
lv.reclaimViews(list);
for (View view : list) {
((Checkable) view).setChecked(false);
}
lv.setChoiceMode(lv.CHOICE_MODE_NONE);
Esto es mejor que usar getChildAt(i) porque ese método jusg le da las vistas actualmente visibles y no tiene en cuenta las vistas internas almacenadas en caché, que no son visibles.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-22 19:14:15
He encontrado que los únicos dos métodos que funcionan aquí (API 19)
son:
- Restablecer el adaptador de lista, que no es deseable porque vuelve a la parte superior de la lista;
- Establecer el modo de elección en
CHOICE_MODE_NONE
en unnew Runnable
Si el modo de elección se cambia sin usar listView.post(new Runnable())
, no funciona. ¿Alguien puede explicarme por qué es esto?
Disculpas por no comentar, no tengo reputación.
Gracias.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-03 10:25:17
No estoy seguro si esto es demasiado tarde solo quería compartir. Creé una intent en la misma página para que una vez que se capturan los datos en los que se hace clic, se recrea una página nueva sin persistencia en los que se hace clic.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-24 10:39:58
No Es un error. Ese comportamiento es necesario para soportar múltiples HID para Android. Por lo tanto, para mostrar el estado de selección solo necesita establecer el modo de elección de la vista de lista y un fondo para soportar el estado seleccionado para el "diseño de elementos de lista", como:
android:background="?android:attr/activatedBackgroundIndicator"
PARA su información: http://android-developers.blogspot.mx/2008/12/touch-mode.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-19 18:52:00