Mantenendo la posizione in ListView dopo la chiamata notifyDataSetChanged

Sto usando un OnScrollListener dinamicamente aggiungere elementi a una ListView quando l’utente scorre verso il basso. Dopo aggiungere i dati per la scheda e la chiamata notifyDataSetChanged, però, la ListView risale fino alla cima. Idealmente, vorrei mantenere la posizione nella ListView. Ogni pensiero su come dovrei farlo?

  • Ciao è possibile si prega di condividere come u conserva e utilizzato attuale stato di visualizzazione elenco in OnScrollListener… sto facendo io stesso, ma ho aggiornato la lista da Async task…….. non funziona in qualche modo
  • Soluzione semplice: stackoverflow.com/a/28149739/1468093
  • utilizzare @KamranAhmed ‘s risposta. soluzione elegante e semplice. infatti corretto anche
InformationsquelleAutor SeanPONeil | 2011-11-26

 

7 Replies
  1. 97

    Questo potrebbe essere quello che si desidera?

    //save index and top position
    int index = mList.getFirstVisiblePosition();
    View v = mList.getChildAt(0);
    int top = (v == null) ? 0 : v.getTop();
    
    //notify dataset changed or re-assign adapter here
    
    //restore the position of listview
    mList.setSelectionFromTop(index, top);

    MODIFICA 28/09/2017:

    L’API ha cambiato un po ‘ a partire dal 2015. È simile, ma ora sarebbe:

    //save index and top position
    int index = mList.FirstVisiblePosition; //This changed
    View v = mList.getChildAt(0);
    int top = (v == null) ? 0 : v.Top; //this changed
    
    //notify dataset changed or re-assign adapter here
    
    //restore the position of listview
    mList.setSelectionFromTop(index, top);
    • Grazie. Se si desidera aggiungere elementi al top della lista senza vedere l’aggiornamento avvenga, è necessario aggiungere il numero di elementi aggiunti all’indice int. int indice = mList.getFirstVisiblePosition() + NUMBER_OF_ADDED_ITEMS;
    • Se setSelection non funziona immediatamente dopo la chiamata notifyDataSetChanged, ecco una soluzione: getListView().postDelayed(new Runnable() { @Override public void run() { getListView().setSelection(8); } }, 500); Android bug è presumibilmente ricevuto, quindi questo dovrebbe essere fissato a un certo punto: code.google.com/p/android/issues/detail?id=6741
    • Perfettamente funzionante. Inoltre, in caso aiuta qualcun altro, questo non era il lavoro per me. Fino a che ho capito in alcuni precedenti infinita saggezza di mio, avevo aggiunto lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL). Non farlo… che a forza di scorrere fino in fondo la tua listview, fino a quando hai tirato la maggior parte dei vostri capelli. hah.
    • Ho usato getScrollX() e setScrollX() invece di getFirstVisiblePosition() e setSelectionFromTop(), che ancora ha causato alcuni piccoli salti durante l’aggiunta di contenuti.
    • Ho usato (non in ritardo) metodo post per farlo funzionare, purtroppo, ancora sfarfallio durante l’aggiornamento.
    • che cosa è mList? È un oggetto di listView classe? E dove devo mettere questo codice, subito dopo listViewObj.setAdapter(adapter)?
    • questo è il copia-incolla da qui, stackoverflow.com/questions/3014089/…
    • Grazie! Questo era quello che mi serviva troppo!
    • Per evitare il flickering, ho seguito le istruzioni da stackoverflow.com/q/19320214/2343626 . Quello che devi fare è registrare un OnPreDrawListener per il controllo listview e quindi si può ignorare il sorteggio richiesta fatta dalla scheda di rete e consentire solo il sorteggio richiesta che è stata fatta quando è chiamato setSelectionFromTop.
    • setSelectionFromTop chiamata richiede un minimo di API di livello 21. Che cosa circa l’esecuzione di pre 21 dispositivi ?

  2. 6

    La situazione:

    Quando si imposta un adattatore per la tua listview, che aggiorna il suo stato. Così, normalmente scorre automaticamente.

    La soluzione:

    Assegnare un adattatore per listview se non ha alcun, il resto solo aggiornare il set di dati per l’assegnazione di un adattatore, non re-impostare la listview.

    Un dettagliato tutorial è spiegato al seguente link;

    Android ListView: Mantenere la posizione di scorrimento quando si aggiorna

    Buona Fortuna!

    • Questo funziona in un modo, come la posizione di scorrimento non si muove se posso aggiungere un ulteriore elemento, ma la lista all’interno di una vista salti giù per ospitare il nuovo elemento.
    • Questa è la soluzione corretta, non di “hacking”, necessario per ottenere qualcosa di semplice.
  3. 0

    Ho implementato il postDelayed e mi è stato sempre tremolante dopo l’aggiornamento. Faccio una ricerca e scoperto che stavo facendo qualcosa di sbagliato. Fondamentalmente io non creare una nuova scheda ogni volta che volevo cambiare i dati. Ho finito di fare in questo modo e funziona:

    //goes into your adapter
    public void repopulateData(String[] objects) {
        this.objects = null;
        this.objects = objects;
        notifyDataSetChanged();
    }
    
    //goes into your activity or list
    if (adapter == null) {
        adapter = new Adapter();
    } else {
        adapter.repopulateData((String[])data);
    }

    Spero che questo aiuta.

  4. 0

    Sto usando

    listView.getFirstVisiblePosition

    per mantenere l’ultima posizione ben visibile.

  5. 0

    Provare questo

          boolean first=true; 
          protected void onPostExecute(Void result) 
          {
    
          if (first == true) {
          listview.setAdapter(customAdapter);
          first=false;
          }
          else
          customAdapter.notifyDataSetChanged();
          }
  6. 0

    Ecco il codice:

    //Save the ListView state (= includes scroll position) as a Parceble
    Parcelable state = listView.onSaveInstanceState();
    
    //e.g. set new items
    listView.setAdapter(adapter);
    
    //Restore previous state (including selected item index and scroll position)
    listView.onRestoreInstanceState(state);  

Lascia un commento