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!

Respuestas:


132

llamar listView.setSelectionAfterHeaderView();para desplazarse hacia arriba


66
así es exactamente como lo hubiera llamado.
markshiz

102

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

list.smoothScrollToPosition(0);

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.


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í.


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.


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.


2

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

        mListView.smoothScrollToPosition(mAdapter.getCount());

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.