Android ListView przewijanie do góry

80

Mam ListViewz niestandardowymi rzędami. Po kliknięciu dowolnego z tych wierszy dane ListView są ponownie generowane. Chciałbym, aby w takim przypadku lista przewijała się z powrotem na górę.

Początkowo próbowałem użyć setSelection(0)w każdym wierszu, OnClickListener aby to osiągnąć, ale nie powiodło się (uważam, że ListView traci pozycję przewijania, gdy jego dane są unieważnione - więc moje wywołanie setSelection jest cofane.Nadal nie rozumiem, w jaki sposób ListView decyduje, gdzie przewinąć po unieważnieniu).

Jedyne działające rozwiązanie, które znam, podał Romain Guy tutaj: http://groups.google.com/group/android-developers/browse_thread/thread/127ca57414035301

Obejmuje View.postto wezwanie do _listView.setSelection(0). Zauważyłem, że działa to dość słabo. Nowo wygenerowana lista pojawia się z niezmienioną lokalizacją przewijania i występuje znaczne opóźnienie, zanim przewinie się z powrotem na górę.

Czy jest lepszy sposób na osiągnięcie tej funkcjonalności?

Każda pomoc byłaby bardzo mile widziana.

Dzięki!

aakash
źródło

Odpowiedzi:

132

zadzwoń, listView.setSelectionAfterHeaderView();aby przewinąć do góry

DB
źródło
66
dokładnie tak bym to nazwał.
markshiz
102

Wiele próbowałem, ale ten zadziałał dla mnie

list.smoothScrollToPosition(0);
N20084753
źródło
3
To jest niesamowite. Zastanawiam się, czy możesz zmienić prędkość przewijania.
theblang
Czy może istnieć również oddzwonienie, aby wiedzieć, kiedy przewijanie się kończy, aby móc przejść do następnego ekranu?
Amol Gupta
41

Po prostu używam listview.setSelection(0);

U mnie działa dobrze.

radhoo
źródło
5

Jeśli potrzebujesz natychmiastowego przewijania zaraz po ListViewzmianie danych karty, zwróć uwagę, że może nie być jeszcze wypełniony. W takim przypadku powinieneś post()swój setSelection()lub setSelectionAfterHeaderView()przez, Handlerwięc zostanie wywołany później w kolejce.

listView.Handler.post(new Runnable() {
            @Override
            public void run() {
                listView.setSelectionAfterHeaderView();    
            }
        });

To zadziałało dla mnie.

Dmitry Polomoshnov
źródło
4

Osobiście polecam znaleźć inny wzorzec interfejsu użytkownika. Możliwe, że użytkownicy uznają Twoje obecne „kliknięcie, a lista zmienia się na miejscu ” za intuicyjne, ale jestem sceptyczny.

Możesz spróbować podklasy ListViewi nadpisanie, layoutChildren()aby przejść do nadklasy, a następnie wywołać setSelection(0)w przypadku, gdy jest to potrzebne. Jeśli „znaczne opóźnienie” jest spowodowane tylko post()wezwaniem, powinno to wyjaśnić sprawę.

CommonsWare
źródło
4
Dzięki za sugestię, niedługo spróbuję. Lista jest zmieniana na miejscu, ponieważ menu nawigacyjne jest wyświetlane w innym miejscu na ekranie - typowe projekty interfejsu użytkownika Androida są mniej dopasowane do moich konkretnych celów interfejsu użytkownika i docelowych użytkowników. Dziękuję również za WSZYSTKĄ twoją pomoc - przeczytałem wiele twoich odpowiedzi na stackoverflow i twoją literaturę CommonsWare, i znacznie pomogli mi w rozpoczęciu korzystania z tej platformy!
aakash
to jest sposób na zrobienie tego, żadnych magicznych metod, tylko czysta logika. Dzięki!
Leo wspiera Monikę Cellio
2

Aby obejść ten problem, możesz utworzyć nowy adapter zawierający nowe ponownie wygenerowane dane, a następnie wywołać ListView.setAdapter. po tym wywołaniu ListView.setSelection (n).

przy okazji, rozwiązanie dostarczone przez oprogramowanie wspólne działa.

shaobin0604
źródło
2

Na inne wymaganie. Jeśli chcesz przewijać w górę, tak jak podczas rozmowy.

        mListView.smoothScrollToPosition(mAdapter.getCount());
Fahad
źródło
2

Ten działał dobrze, gdy chcesz skupić edittext z nagłówka listy

listview.setSelectionFromTop(0,0);

Jeśli chcesz wybrać konkretny widok indeksu z widoku listy, to

listview.setSelection(index); // o for top
Sampath Kumar
źródło