Elenco visualizzato Scorrere fino alla fine dell'elenco dopo aver aggiornato l'elenco


292

Vorrei assicurarmi che l'elenco venga fatto scorrere fino in fondo, dopo aver aggiornato la visualizzazione elenco utilizzando listAdapter, in modo che visualizzi l'ultimo elemento inserito nell'elenco. Come posso fare questo ?

Ci ho provato ma senza fortuna:

lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

grazie


prova a farlo funziona ... messageListView.setTranscriptMode (ListView.TRANSCRIPT_MODE_NORMAL); messagesListView.setStackFromBottom (true);
Superdev,

lv.setTranscriptMode (ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL) garantisce solo che listView verrà fatto scorrere verso il basso dopo aver chiamato adapter.notifyDataSetChanged. Se questo non funziona, prova a definire questa proprietà in xml come puoi vedere nei post qui sotto.
Tommaso,

Risposte:


418

Supponendo di sapere quando i dati dell'elenco sono stati modificati, è possibile indicare manualmente all'elenco di scorrere verso il basso impostando la selezione dell'elenco sull'ultima riga. Qualcosa di simile a:

private void scrollMyListViewToBottom() {
    myListView.post(new Runnable() {
        @Override
        public void run() {
            // Select the last row so it will scroll into view...
            myListView.setSelection(myListAdapter.getCount() - 1);
        }
    });
}

@Bhupendra che non è necessario. Puoi anche fare a meno del thread, come mostrato nella risposta di Warting.
Sagarpatidar,

2
@Bhupendra setSelection () aggiorna l'interfaccia utente. Chiamando post (Runnable) sulla vista, ti assicuri che il codice Runnable sia eseguito sul thread dell'interfaccia utente Android. In genere, fallo in questo modo, a meno che tu non sappia che sei già nel thread dell'interfaccia utente o che non lo stia assicurando in qualche altro modo.
Mason Lee,

5
sembra anche che l'uso di post su un adattatore appena impostato provochi l'animazione di scorrimento assicurandosi di essere nel thread principale e l'utilizzo di setSelection immediatamente dopo aver impostato l'adattatore non provoca l'animazione di scorrimento
Gianluca P.

1
@SaifHamed come commentato da Mason Lee sulla risposta di Kevin, questo fa sì che gli elenchi brevi dispongano di uno spazio "vuoto" nella parte superiore della vista anziché nella parte inferiore, che molto probabilmente non è il comportamento previsto.
precipitare il

16
puoi anche usare myListView.smoothScrollToPosition (myListAdapter.getCount () - 1); per uno scorrimento fluido
Zar E Ahmer,

238

Devi utilizzare questi parametri nella visualizzazione elenco:

  • Scorrere lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

  • Imposta la fine dell'elenco in fondo lv.setStackFromBottom(true);

È inoltre possibile impostare questi parametri in XML, ad es. come questo:

<ListView
   ...
   android:transcriptMode="alwaysScroll"
   android:stackFromBottom="true" />

27
Si noti che con questo approccio, le righe "impilano dal basso" della vista man mano che vengono aggiunte. Ciò significa che gli elenchi brevi avranno uno spazio "vuoto" nella parte superiore della vista anziché nella parte inferiore, che non è sempre quello che si desidera.
Mason Lee,

2
Domanda rapida: in che modo è possibile animare lo scorrimento? Perché al momento quando informoDataSetChanged () salta senza animazione?!?
Georg,

@Georg Hai forse disabilitato le animazioni in Opzioni sviluppatore sul tuo dispositivo?
JonasCz - Ripristina Monica

35

Una combinazione di TRANSCRIPT_MODE_ALWAYS_SCROLL e setSelection ha fatto sì che funzionasse per me

ChatAdapter adapter = new ChatAdapter(this);

ListView lv = (ListView) findViewById(R.id.chatList);
lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lv.setAdapter(adapter);

adapter.registerDataSetObserver(new DataSetObserver() {
    @Override
    public void onChanged() {
        super.onChanged();
        lv.setSelection(adapter.getCount() - 1);    
    }
});

29

Ho avuto successo usando questo in risposta a un clic sul pulsante, quindi immagino che tu possa usarlo anche dopo aver aggiornato i tuoi contenuti:

myListView.smoothScrollToPosition(theListAdapter.getCount() -1);

1
Questa è un'ottima soluzione Semplice, una riga.
Josh Larson,

12

Per ottenere questo in un ListFragment:

getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 
getListView().setStackFromBottom(true);`

Aggiunta questa risposta perché se qualcuno fa una ricerca su Google per lo stesso problema con ListFragment, trova questo ..

Saluti


9

Utilizzo: imposta la fine dell'elenco in fondo lv.setStackFromBottom(true);

Ha funzionato per me e l'elenco viene automaticamente spostato fino in fondo quando viene visualizzato per la prima volta. L'elenco scorre quindi come dovrebbe TRANSCRIPT_MODE_ALWAYS_SCROLL.


6
Si noti che con questo approccio, le righe "impilano dal basso" della vista man mano che vengono aggiunte. Ciò significa che gli elenchi brevi disporranno di uno spazio "vuoto" nella parte superiore della vista anziché nella parte inferiore.
Mason Lee,

5

Io uso

setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);

per aggiungere voci in basso e le voci più vecchie scorrono dall'alto, come una trascrizione della chat


Chiamare getListView().smoothScrollToPosition(getListAdapter.getCount() - 1);in avvio per scorrere verso il basso all'inizio dell'attività.
palindrom,

4

La soluzione più semplice è:

    listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setStackFromBottom(true);

3

La modalità di trascrizione è quella che desideri ed è utilizzata da Google Talk e dall'applicazione SMS / MMS. Quando si aggiungono elementi, si chiama correttamente notificationDatasetChanged () sull'adattatore?


sì, lo sono. l'elenco viene aggiornato correttamente, ma inizia sempre dall'alto. Mi serve solo per aggiungere il nuovo elemento e scorrere sempre fino alla fine dell'elenco.
jramirez,

La modalità di trascrizione è effettivamente disabilitata dall'app SMS. Non ricordo esattamente perché.
Timmmm,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.