Mantener/Guardar/Restaurar la posición de desplazamiento al regresar a ListView
Tengo un largo ListView
por el que el usuario puede desplazarse antes de volver a la pantalla anterior. Cuando el usuario ListView
vuelva a abrir esto, quiero que la lista se desplace al mismo punto que estaba anteriormente. ¿Alguna idea sobre cómo lograr esto?
Prueba esto:
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
// ...
// restore index and position
mList.setSelectionFromTop(index, top);
Explicación:
ListView.getFirstVisiblePosition()
devuelve el elemento de lista más visible. Pero este elemento puede estar parcialmente desplazado fuera de la vista, y si desea restaurar la posición de desplazamiento exacta de la lista, necesita obtener este desplazamiento. Entonces ListView.getChildAt(0)
devuelve el View
elemento de la lista superior y luego View.getTop() - mList.getPaddingTop()
devuelve su desplazamiento relativo desde la parte superior del archivo ListView
. Luego, para restaurar la ListView
posición de desplazamiento de , llamamos ListView.setSelectionFromTop()
con el índice del elemento que queremos y un desplazamiento para posicionar su borde superior desde la parte superior del ListView
.
Parcelable state;
@Override
public void onPause() {
// Save ListView state @ onPause
Log.d(TAG, "saving listview state");
state = listView.onSaveInstanceState();
super.onPause();
}
...
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set new items
listView.setAdapter(adapter);
...
// Restore previous state (including selected item index and scroll position)
if(state != null) {
Log.d(TAG, "trying to restore listview state");
listView.onRestoreInstanceState(state);
}
}
Adopté la solución sugerida por @(Kirk Woll) y me funciona. También he visto en el código fuente de Android para la aplicación "Contactos" que utilizan una técnica similar. Me gustaría agregar algunos detalles más: En la parte superior de mi clase derivada de ListActivity:
private static final String LIST_STATE = "listState";
private Parcelable mListState = null;
Luego, algún método anula:
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
mListState = state.getParcelable(LIST_STATE);
}
@Override
protected void onResume() {
super.onResume();
loadData();
if (mListState != null)
getListView().onRestoreInstanceState(mListState);
mListState = null;
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
mListState = getListView().onSaveInstanceState();
state.putParcelable(LIST_STATE, mListState);
}
Por supuesto, "loadData" es mi función para recuperar datos de la base de datos y ponerlos en la lista.
En mi dispositivo Froyo, esto funciona tanto cuando cambias la orientación del teléfono como cuando editas un elemento y vuelves a la lista.