2012-08-09 7 views
6

Ho un listview che ottiene ulteriori visualizzazioni aggiunte su richiesta, gestite da un BaseAdapter. Come posso mantenere la posizione di scorrimento dopo l'aggiornamento?Android ListView - consente di tornare all'inizio dell'aggiornamento

So che è stato chiesto alcune volte, ma ogni volta è stata avanzata la stessa soluzione, che ho provato, ovvero chiamare adapter.notifyDataSetChanged(); dopo aver aggiornato ArrayList che contiene il contenuto dell'elenco.

Come si può garantire che la posizione di scorrimento venga mantenuta?

+1

si prega di includere il vostro codice. –

risposta

12

implementare un OnScrollListener nella classe di attività e quindi utilizzare il seguente codice:

int currentFirstVisibleItem, currentVisibleItemCount, currentTotalItemCount; 
public void onScroll(AbsListView view, int firstVisibleItem, 
     int visibleItemCount, int totalItemCount) { 
    this.currentFirstVisibleItem = firstVisibleItem; 
    this.currentVisibleItemCount = visibleItemCount; 
    this.currentTotalItemCount = totalItemCount; 
} 

public void onScrollStateChanged(AbsListView view, int scrollState) { 
    this.currentScrollState = scrollState; 
    this.isScrollCompleted(); 
} 

private void isScrollCompleted() { 

    if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) { 
     if (this.currentVisibleItemCount > 0 
       && this.currentScrollState == SCROLL_STATE_IDLE) { 

      //Do your work 
     } 
    } 
} 

Se si utilizza AsyncTask per l'aggiornamento dei dati, allora si può includi quanto segue nel tuo PostExecute() per mantenere la posizione di scorrimento:

list.setAdapter(adapter); 
list.setSelectionFromTop(currentFirstVisibleItem, 0); 

Spero che questo aiuti.

+0

cosa intendi per // fai il tuo lavoro. Cos'altro ci sarebbe da fare? – ajacian81

+0

In // Esegui il tuo lavoro, puoi scrivere il tuo codice come qualunque cosa tu voglia fare al completamento dello scroll. Ad esempio, come Facebook se vuoi caricare più dati su Scroll down, puoi scrivere il codice per questo qui .. –

+0

Questo funziona bene per aggiungere footer ... I cosa aggiungere un'intestazione al mio listview per l'aggiornamento. Quindi per favore dammi una condizione per aggiungere l'intestazione al listview – Arun

5

L'approccio che prendo è di chiamare ListView.setSelection(position) per scorrere fino allo position desiderato dopo l'aggiornamento.

A seconda di dove si sta chiamando, potrebbe essere necessario chiamare requestFocusFromTouch prima di chiamare setSelection per assicurarsi che l'elemento venga posizionato correttamente.

+0

La chiamata a requestFocusFromTouch è stato il passaggio cruciale per me! – Newtz

+1

YESSSSSSSSSSSSS, ti abbraccerei se potessi. Così tanto tempo per risolvere questo problema – Vfleitao

2

Si può provare questo:

//Get the top position from the first visible element 
int fVisible = list.getFirstVisiblePosition(); 
View vFirst = list.getChildAt(0); 
int pos = 0; 
if (vFirst != null) pos = vFirst.getTop(); 

//Restore the position 
list.setSelectionFromTop(fVisible, pos); 
+0

Sfortunatamente, incredibilmente quello non ha funzionato. Dopo aver inserito la registrazione, dopo averlo fatto scorrere nella posizione desiderata, è sufficiente ripristinare la posizione e tornare all'inizio. – ajacian81

+0

ajacian81 Controlla la nuova soluzione che ho postato ... Spero che questo aiuti ... –

3

Questo codice vi aiuterà fuori ....

// get position of listview 
int index = listView.getFirstVisiblePosition(); 
View v = listView.getChildAt(0); 
int top = (v == null) ? 0 : v.getTop(); 

// notify dataset changed or re-assign adapter here 

//re-assign the position of listview after setting the adapter again 
listView.setSelectionFromTop(index, top); 

Saluti :)

+0

Flawless, è come se l'adattatore mai cambiato, oltre ad aggiornare la vista rilevante, che nel mio caso alterna l'immagine cliccata nel layout lista! Grazie molto!! – WallyHale

0

si può fare come di seguito. Se vuoi caricare più dati con lo scorrimento verso il basso, questo cambierà.

int currentFirstVisibleItem, currentScrollState; 
int countChange = 0; 
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
    Log.d("Scroll", "Scrolling"); 
    this.currentFirstVisibleItem = firstVisibleItem; 
    countChange = 0;//during touching you can decide not to refresh by scroll 
} 

public void onScrollStateChanged(AbsListView view, int scrollState) { 
    Log.d("Scroll", "Changed"); 
    this.currentScrollState = scrollState; 
    if (scrollState == SCROLL_STATE_TOUCH_SCROLL) { 
     countChange = 0; 
    } 
    if (++countChange > 1) { 
     //scroll to top and release touch change=2. Simple scroll and release touch change=1 
     this.isScrollCompleted(); 
     countChange = 0; 
    } 
} 

private void isScrollCompleted() { 
    Log.d("Load", "Reload"); 
    if (currentFirstVisibleItem == 0) { 
     //Your loading go here 
    } 
} 
+0

Sì, questa è la forma del codice non dell'immagine. Ho appena provato a scrivere come codice. Non è una solita scrittura come il codice in IDE. –