2013-03-16 35 views
10

Używam CWAC's EndlessAdapter do osiągnięcia nieskończonego przewijania listView.Endless adapter dla ViewPager

Chciałbym osiągnąć odpowiednik dla ViewPagera. Niestety, PageAdapter i ListAdapter nie mają tej samej wspólnej podstawowej klasy.

Jaki jest najlepszy sposób, aby rozwiązać ten problem? Czy istnieje biblioteka, która już to obsługuje?

+1

Jeśli już zaimplementowałeś, podziel się swoim rozwiązaniem na gitHub lub gdziekolwiek chcesz :) –

Odpowiedz

14

Jaki jest najlepszy sposób na rozwiązanie tego problemu?

Dodaj "niekończącą się" logikę do własnej implementacji PagerAdapter. Lub, jeśli chcesz, spróbuj stworzyć dekorację PagerAdapter, sposób, w jaki EndlessAdapter zdobi zwykły .

To ostatnie może być trudne, biorąc pod uwagę, że PagerAdapter jest przeznaczony do stron, które mają być widokami lub fragmentami, a obsługa fragmentów wewnątrz klas takich jak FragmentPagerAdapter jest nieco przerażająca.

Czy istnieje biblioteka, która już to obsługuje?

Brak, o którym jestem świadomy.

Głównie dlatego, że przypadek użycia nie wydaje się zbyt przekonujący. Dzięki ListView użytkownik może rzucić palcem na listę, bardzo szybko przewijając dziesiątki lub setki rzędów. Dlatego użycie "dotarliśmy do końca", ponieważ wyzwalacz do załadowania większej ilości danych wydaje się uzasadniony. W przypadku modelu ViewPager jednak uzyskanie końca jest zazwyczaj znacznie dłuższe, szczególnie w przypadku, gdy użytkownik nie używa PagerTabStrip lub odpowiednika. Dlatego czekanie, aż użytkownik dotrze do końca, aby rozpocząć ładowanie dodatkowych danych, wydaje się być denerwujące dla użytkownika - przez cały czas pobierano więcej danych, ale go nie używano.

Alternatywą jest zarejestrowanie urządzenia ViewPager.OnPageChangeListener przy użyciu swojego telefonu ViewPager. Kiedy onPageSelected(), a ty uważasz się za blisko końca, uruchom AsyncTask (lub cokolwiek innego), aby zebrać więcej danych. Połów jest to, że będziesz musiał zaktualizować dane używane przez PagerAdapter i zadzwonić notifyDataSetChanged() na tym adapterze, gdy dane zostały zaktualizowane.

+0

Są oczywiście zastosowania - szczególnie, gdy fragmenty nie polegają na załadowaniu ogromnych ilości danych, ale na przykład na pozycji viewpagera odzwierciedla tylko indeks danych, na które patrzysz. Na przykład: Chcę mieć ViewPager, który ma stronę dziennie, począwszy od dzisiaj i rozszerzającą się w prawo do - no, nieskończoności, jeśli chcesz. Przerzucanie stron oznacza tylko przełączenie dnia na wyświetlanie, a dane do wyświetlenia są obliczane, a nie ładowane. Nadal nie jestem pewien, jak to zaimplementować ... – Zordid

+0

@Zordid: Jak zauważyłem w mojej odpowiedzi, aby utworzyć "nieskończony" 'ViewPager', musiałbyś mieć tę logikę w swojej niestandardowej implementacji' PagerAdapter'. Ani 'FragmentPagerAdapter' ani' FragmentStatePagerAdapter' nie są w stanie tego zrobić, ponieważ zabraknie pamięci, ponieważ utworzą nowe fragmenty dla każdej strony. – CommonsWare

+0

Obecnie używam 'FragmentStatePagerAdapter', jak dotąd nie osiągnąłem limitu. Ale nie byłem pewien co do tego z powodu zapisywania stanów - moje widoki naprawdę nie mają stanu, ponieważ każda strona odzwierciedla tylko wybrany dzień w kalendarzu ... Chyba powinienem przepisać to ponownie z moim niestandardowym adapterem - lub po prostu przełącz się na widoki zamiast fragmentów ... – Zordid

5

Może można „udawać się” w sposób następujący:

Jesteś prawdopodobnie wykazują szereg ogrrrromny stron. Użyj FragmentStatePagerAdapter Klasa: https://developer.android.com/reference/android/support/v13/app/FragmentStatePagerAdapter.html

Wdrożenie metody getCount wracając Integer.MAX_VALUE.
Zastosuj metodę getItemPosition, zwracając zawsze POSITION_NONE.
Zastosuj metodę getItem, jak chcesz, zwracając odpowiedni Fragment.

Następnie, gdy rozpoczyna się działanie hosta ViewPager, ustaw początkową pozycję ViewPagera na bardzo dużą liczbę, np. viewPager.setCurrentItem(Integer.MAX_VALUE/2);.

Nie próbowałem tego sam ..., YMMV! :)

6
@Override 
public int getCount() { 
    return (Integer.MAX_VALUE); 
    //artificially large value for infinite scrolling 
} 

public int getRealCount(){ 
//Do something to return the actual number of objects. 
} 


@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    int virtualPosition = position % getRealCount(); 
    return instantiateVirtualItem(container, virtualPosition); 
} 

public Object instantiateVirtualItem(ViewGroup container, final int position) {    
//Do the required part here 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    int virtualPosition = position % getRealCount(); 
    destroyVirtualItem(container, virtualPosition, object); 
} 


public void destroyVirtualItem(ViewGroup container, int position, Object object){ 
    container.removeView((View) object);    
} 

Teraz najważniejsza część

pager.setOffscreenPageLimit(10); //your choice 
pager.setCurrentItem(Integer.MAX_VALUE/2,false); 
//pager is the ViewPager object 

PS: Mam powodzeniem wdrożony ten. Zapytaj, czy nadal masz wątpliwości.

+0

Używam również tego wzorca, ale szukam lepszego rozwiązania ... – stefan

+0

@stefan poinformuj tutaj, kiedy go znajdziesz. – Shakti

+1

Odgadnij jedyną opcję, możesz zmodyfikować ViewPager. W moim przypadku, w kalendarzu z możliwością przesuwania, byłoby dobrze, gdyby przedmiot został zakupiony przez DateTime zamiast Integer ... – stefan