Android ListView desplazándose hacia arriba

80

Tengo una ListViewcon filas personalizadas. Cuando se hace clic en cualquiera de estas filas, se regeneran los datos de ListView. Me gustaría que la lista volviera a la parte superior cuando esto suceda.

Inicialmente intenté usar setSelection(0)en cada fila OnClickListener para lograr esto, pero no tuve éxito (creo que porque ListView pierde su posición de desplazamiento cuando se invalidan sus datos, por lo que mi llamada a setSelection se deshace. Todavía no entiendo cómo ListView decide dónde desplazarse sin embargo, después de la invalidación).

La única solución de trabajo que conozco fue dada por Romain Guy aquí: http://groups.google.com/group/android-developers/browse_thread/thread/127ca57414035301

Implica ( View.post) hacer la llamada a _listView.setSelection(0). Encontré que esto funcionaba bastante mal. La lista recién generada aparece con su ubicación de desplazamiento sin cambios y hay una demora considerable antes de que vuelva a la parte superior.

¿Existe alguna forma mejor de lograr esta funcionalidad?

Cualquier ayuda será muy apreciada.

¡Gracias!

aakash
fuente

Respuestas:

132

llamar listView.setSelectionAfterHeaderView();para desplazarse hacia arriba

DB
fuente
66
así es exactamente como lo hubiera llamado.
markshiz
102

He intentado mucho, pero este funcionó para mí.

list.smoothScrollToPosition(0);
N20084753
fuente
3
Esto es asombroso. Me pregunto si puede cambiar la velocidad de desplazamiento.
theblang
¿También puede haber una devolución de llamada para saber cuándo termina el scoll para poder navegar a la siguiente pantalla?
Amol Gupta
41

Yo simplemente uso listview.setSelection(0);

Funciona bien para mi.

radhoo
fuente
5

Si necesita un desplazamiento instantáneo justo después ListViewde cambiar los datos del adaptador, preste atención a que es posible que aún no se haya completado. En este caso, debe post()su setSelection()o setSelectionAfterHeaderView()via Handlerpara que se llame más tarde en la cola.

listView.Handler.post(new Runnable() {
            @Override
            public void run() {
                listView.setSelectionAfterHeaderView();    
            }
        });

Esto funcionó para mí.

Dmitry Polomoshnov
fuente
4

Personalmente, te recomiendo que encuentres un patrón de interfaz de usuario diferente. Es posible que los usuarios encuentren su enfoque actual de "clic, y la lista cambia in situ " intuitivo, pero soy escéptico.

Puede intentar subclasificar ListViewy anular layoutChildren()para encadenar a la superclase, luego llamar setSelection(0)en el caso que sea necesario. Si el "retraso considerable" se debe sólo a la post()llamada, esto debería aclararlo.

CommonsWare
fuente
4
Gracias por la sugerencia, lo intentaré pronto. La lista se cambia in situ porque las rutas de navegación se muestran en otras partes de la pantalla; los diseños típicos de la interfaz de usuario de Android son menos adecuados para mis objetivos específicos de la interfaz de usuario y los usuarios objetivo. Además, gracias por TODA su ayuda: he leído varias de sus respuestas de stackoverflow y su literatura de CommonsWare, ¡y me han ayudado significativamente a comenzar en esta plataforma!
aakash
esta es la forma de hacerlo, sin métodos mágicos, solo lógica pura. ¡Gracias!
Leo apoya a Monica Cellio
2

como solución alternativa, puede crear un nuevo adaptador que contenga los nuevos datos regenerados y luego llamar a ListView.setAdapter. después de esa llamada ListView.setSelection (n).

por cierto, la solución proporcionada por commonsware está funcionando.

shaobin0604
fuente
2

En algún requisito diferente. Si desea desplazarse hacia arriba como si estuviera chateando.

        mListView.smoothScrollToPosition(mAdapter.getCount());
Fahad
fuente
1

Este funcionó bien cuando desea enfocar el texto de edición del encabezado de la vista de lista

listview.setSelectionFromTop(0,0);

Si desea seleccionar la vista de índice particular de la vista de lista, entonces

listview.setSelection(index); // o for top
Sampath Kumar
fuente