412 votes

Position de défilement de la maintenir/sauvegarder/restaurer lors du retour à un ListView

J’ai une longue que l’utilisateur peut faire défiler autour avant de retourner à l’écran précédent. Lorsque l’utilisateur ouvre ce encore une fois, je veux la liste pour faire défiler jusqu’au même point qu’il l’était auparavant. Toutes les idées sur la façon d’y parvenir ?

641voto

ian Points 6471

Essayez ceci:

// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

// ...

// restore index and position
mList.setSelectionFromTop(index, top);

Explication:

ListView.getFirstVisiblePosition() retourne le sommet visible de l'élément de liste. Mais cet élément peut être partiellement défilé de mode, et si vous souhaitez restaurer l'exacte position de défilement de la liste dont vous avez besoin pour obtenir ce décalage. Donc, ListView.getChildAt(0) renvoie l' View pour le premier élément de la liste, puis View.getTop() retourne sa relative offset à partir du haut de l' ListView. Alors, pour rétablir l' ListView's la position de défilement, nous appelons ListView.setSelectionFromTop() avec l'index de l'élément que nous voulons et un décalage de la position de son bord supérieur du haut de l' ListView.

554voto

Eugene Mymrin Points 2787
<pre><code></code><p><strong>Mise en garde</strong></p><p>Si listView est un fragment inférieur dans le backstack, la variable de listView peut être nulle. Cela pourrait se produire si vous poussez un autre fragment dans la backstack, puis l’appareil pivote (ou le fragment supérieur est redémarré pour toute autre raison).</p><p><code></code>ou être prêt pour l’app s’écraser en raison d’une NullPointerException.</p></pre>

54voto

Giorgio Barchiesi Points 2023

J'ai adopté la solution proposée par @(Kirk Woll), et cela fonctionne pour moi. J'ai également vu dans le code source Android pour les "Contacts" de l'app, qu'ils utilisent une technique similaire. Je voudrais ajouter quelques précisions: Sur le dessus sur ma ListActivity classe dérivée de:

private static final String LIST_STATE = "listState";
private Parcelable mListState = null;

Ensuite, certains remplacements de méthode:

@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);
}

Bien sûr, "loadData" est ma fonction pour récupérer des données à partir de la DB et de la mettre sur la liste.

Sur mon Froyo appareil, cela fonctionne à la fois lorsque vous modifiez l'orientation du téléphone, et lorsque vous modifiez un élément, et revenir à la liste.

26voto

Francesco Laurita Points 12027

Un moyen très simple :

La méthode setSelection se réinitialise la liste pour l’élément fourni. Si ce n’est pas en contact mode de l’élément sera effectivement sélectionné si en contact mode de l’élément sera placé seulement sur écran.

Une approche plus complexe :

17voto

shalafi Points 779

J’ai trouvé quelque chose d’intéressant à ce sujet.

J’ai essayé setSelection et scrolltoXY mais il ne fonctionne pas du tout, la liste est restée dans la même position, après quelques tâtonnements, j’ai obtenu le code suivant qui fonctionne

Si au lieu de poster le Runnable vous essayez runOnUiThread il ne fonctionne pas ou l’autre (au moins sur certains appareils)

Il s’agit d’une solution de contournement très étrange pour quelque chose qui devrait être simple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X