2012-04-09 24 views
81

Fragmenty, których używam w mojej instancji ViewPager, wymagają dużego nakładu zasobów, więc chciałbym załadować tylko jeden plik naraz. Kiedy próbuję następujące:ViewPager.setOffscreenPageLimit (0) nie działa zgodnie z oczekiwaniami.

mViewPager.setOffscreenPageLimit(0); 
mViewPager.setAdapter(mPagerAdapter); 

Moja FragmentStatePagerAdapter.getItem(int position) funkcja nadpisywania nazywa się 3 razy, co jest, co się dzieje, gdy zgłoszę mViewPager.setOffscreenPageLimit(1). Spodziewam się, że zostanie on wywołany tylko raz, ponieważ podałem 0 stron poza ekranem.

Wydaje mi się, że wszystko dzwonię poprawnie, ponieważ jeśli zadzwonię pod numer mViewPager.setOffscreenPageLimit(2), zostanie on wywołany 5 razy, jak można się spodziewać.

Czy ViewPager wymaga co najmniej 1 strony poza ekranem, czy też robię coś nie tak?

+6

Dodałem żądanie funkcji: https://code.google.com/p/android/issues/detail?id=56667 –

+0

https://stackoverflow.com/a/44405015/7874047 –

Odpowiedz

96

Does ViewPager wymagają minimum 1 OffScreen stron

Tak. Jeśli mam poprawnie czytania kodu źródłowego, powinieneś otrzymywać ostrzeżenie o tym w LogCat, coś takiego:

Requested offscreen page limit 0 too small; defaulting to 1 
+0

Dobrze, że jesteś . Będę musiał zoptymalizować moje początkowe czasy ładowania w inny sposób. Twoje zdrowie. –

+3

To nie jest rozwiązanie! Chcę załadować tylko 1 fragment nie 2. Z pewnością jest to możliwe? – HGPB

+10

@Haraldo: "Z pewnością jest to możliwe?" - nie za pomocą 'ViewPager'. 'ViewPager' tworzy te fragmenty w taki sposób, że widoki istnieją, więc użytkownik może przesuwać między nimi, z animowanym efektem pokazującym, że stary widok zsuwa się z ekranu, a nowy widok przesuwa się na ekran. Możesz spróbować napisać własną "ViewPager", która może przeskakiwać między rzeczami, które nie istnieją. Więcej informacji na ten temat można znaleźć na stronie https://code.google.com/p/android/issues/detail?id=56667#c3 – CommonsWare

0

dla funkcji „instantiateItem”, tylko przygotować fragment, ale nie załadować ciężki treści .

Użyj "onPageChangeListener", aby za każdym razem, gdy wchodzisz na określoną stronę, ładujesz jej ciężką zawartość i wyświetlasz.

94

Najlepszym sposobem, że znalazłem setUserVisibleHint
dodać to do fragmentu

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) { 
     // load data here 
    }else{ 
     // fragment is no longer visible 
    } 
} 
+1

+++++ za to rozwiązanie !!! dzięki, po dodaniu tego kodu dostałem NPL po raz pierwszy, dodałem po prostu blok catch i jego prace idealne dla mnie !!! –

+1

W przypadku korzystania z tego nie wczytuje daty na fragmencie SecondViewPager, a na drugim fragmencie danych ładowania trzeciego fragmentu. Czy ktoś może mi pomóc? – Arshad

+0

Czy brakuje mi czegoś, setUserVisibleHint wywoływana przed onCreateView –

0

może to być stary wątek, ale to wydaje się działać dla mnie. Zastąpić tę funkcję:

@Override 
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible); 

    if (menuVisible) { 
     /** 
     * Load your stuffs here. 
     */ 
    } else { 
     /** 
     * Fragment not currently Visible. 
     */ 
    } 
} 

szczęśliwe codings ...

+0

jak zarządzać za pomocą webviewclient? –

+0

whats na stronie internetowej? Sugeruję utworzenie dla tego nowego wątku. – ralphgabb

1

ViewPager jest domyślnym załadować następną stronę (fragment), których nie można zmienić przez setOffscreenPageLimit (0). Ale możesz zrobić coś, aby włamać się. Możesz zaimplementować funkcję onPageSelected w Aktywności zawierającej ViewPager. W następnym fragmencie (którego nie chcesz ładować), piszesz funkcję, powiedzmy showViewContent(), w której umieszczasz cały użyteczny kod init i nic nie robisz przed metodą onResume(). Następnie wywołaj funkcję showViewContent() na stronie onPageSelected. Mam nadzieję, że to pomoże.

3

Możesz spróbować tak:

public abstract class LazyFragment extends Fragment { 
 
    protected boolean isVisible; 
 
    /** 
 
    * 在这里实现Fragment数据的缓加载. 
 
    * @param isVisibleToUser 
 
    */ 
 
    @Override 
 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
 
     super.setUserVisibleHint(isVisibleToUser); 
 
     if(getUserVisibleHint()) { 
 
      isVisible = true; 
 
      onVisible(); 
 
     } else { 
 
      isVisible = false; 
 
      onInvisible(); 
 
     } 
 
    } 
 
    protected void onVisible(){ 
 
     lazyLoad(); 
 
    } 
 
    protected abstract void lazyLoad(); 
 
    protected void onInvisible(){}

protected abstract void lazyLoad(); 
protected void onInvisible(){} 
6

najpierw dodać

boolean isFragmentLoaded = false; 

niż

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser && !isFragmentLoaded) { 
     //Load Your Data Here like.... new GetContacts().execute(); 

     isFragmentLoaded = true; 
    } 
else{ 
    } 
} 
+3

, ale ta metoda wywołuje przed onCreateView – Nepster

0

I niby o f mają ten sam problem. Znalazłem użyteczny kod na tej stronie i dokonałem transformacji.

Min. Int dla mViewPager.setOffscreenPageLimit (...); wynosi 1, więc nawet jeśli zmienisz go na 0, nadal będziesz mieć załadowane 2 strony.

Pierwszą rzeczą do zrobienia jest stworzenie static int będziemy nazywać maxPageCount i zastąpić FragmentStatePagerAdapter metody GetCount(), aby powrócić maxPageCount:

@Override 
    public int getCount() { 
     return maxPageCount; 
    } 

Tworzenie następnie statyczną metodę dostępną z dowolnego miejsca w programie, który będzie pozwalają na zmianę tej MAXCOUNT:

public static void addPage(){ 
    maxPageCount++; //or maxPageCount = fragmentPosition+2 
    mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here. 
} 

teraz zainicjować maxPageCount do 1. Kiedy tylko chcesz, możesz dodać kolejną stronę. W moim przypadku, gdy potrzebowałem, aby użytkownik potraktował bieżącą stronę jako pierwszą, zanim wygeneruje drugą. Robi to, a następnie bez problemu może przesuwać do następnej strony.

Mam nadzieję, że komuś pomóż.

Powiązane problemy