2012-04-09 11 views
81

I frammenti che utilizzo nell'istanza ViewPager sono piuttosto intensi in termini di risorse, quindi mi piacerebbe solo caricarne uno alla volta. Quando provo il seguente:ViewPager.setOffscreenPageLimit (0) non funziona come previsto

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

mio FragmentStatePagerAdapter.getItem(int position) funzione di override viene chiamato 3 volte, il che è ciò che accade quando chiamo mViewPager.setOffscreenPageLimit(1). Mi aspetterei che venga chiamato una sola volta, perché ho specificato 0 pagine fuori schermo.

Credo di chiamare tutto correttamente, perché se chiamo mViewPager.setOffscreenPageLimit(2), FragmentStatePagerAdapter.getItem(int position) viene chiamato 5 volte come mi aspetterei.

ViewPager richiede almeno 1 pagine fuori schermo o sto facendo qualcosa di sbagliato qui?

+6

Ho una richiesta di funzionalità: https://code.google.com/p/android/issues/detail?id=56667 –

+0

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

risposta

96

fa ViewPager richiedono un minimo di 1 fuori campo pagine

Sì. Se io sto leggendo il codice sorgente in modo corretto, si dovrebbe essere sempre un avvertimento su questo in LogCat, qualcosa come:

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

Hai ragione . Dovrò ottimizzare i miei tempi di caricamento iniziali in un altro modo. Saluti. –

+3

Questa non è una soluzione! Voglio caricare solo 1 frammento non 2. Sicuramente questo è possibile in qualche modo? – HGPB

+10

@ Haraldo: "Sicuramente questo è possibile in qualche modo?" - non con 'ViewPager'. 'ViewPager' crea questi frammenti in modo che le viste esistano, in modo che l'utente possa scorrere tra di loro, con l'effetto animato che mostra la vecchia vista che scorre dallo schermo e la nuova vista che scorre sullo schermo. Sei libero di provare a scrivere il tuo 'ViewPager' che può scorrere tra le cose che non esistono. Puoi leggere ulteriori informazioni al riguardo su https://code.google.com/p/android/issues/detail?id=56667#c3 – CommonsWare

0

per la funzione "instantiateItem", basta preparare il frammento, ma non si carica il contenuto pesante .

Utilizzare "onPageChangeListener", in modo che ogni volta che si accede a una pagina specifica, si carichi il suo contenuto pesante e lo si mostri.

94

Il modo migliore che ho trovato è stato setUserVisibleHint
aggiungere questo al vostro frammento

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

+++++ per questa soluzione !!! grazie, dopo aver aggiunto questo codice ho ottenuto NPL per la prima volta, ho appena provato try catch block e le sue opere perfette per me !!! –

+1

Durante l'utilizzo non carica la data sul frammento secondViewPager, sul secondo frammento i suoi dati di caricamento del terzo frammento. Qualcuno mi può aiutare? – Arshad

+0

Mi manca qualcosa, setUserVisibleHint chiamato prima su onCreateView –

0

questo può essere thread vecchio, ma questo sembra funzionare per me. Override questa funzione:

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

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

codifiche felici ...

+0

come gestire con webviewclient? –

+0

che cosa è sul webview? Ti suggerisco di creare un nuovo thread per questo. – ralphgabb

1

ViewPager è predefinito per caricare la pagina successiva (frammento), che non si può cambiare da setOffscreenPageLimit (0). Ma puoi fare qualcosa per hackerare. È possibile implementare la funzione onPageSelected in Activity contenente ViewPager. Nel prossimo frammento (che non vuoi caricare), scrivi una funzione diciamo showViewContent() dove inserisci tutto il codice init che consuma risorse e non fai nulla prima del metodo onResume(). Quindi chiama la funzione showViewContent() all'interno di onPageSelected. Spero che questo ti sia d'aiuto.

3

Si può provare in questo modo:

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

First Aggiungi

boolean isFragmentLoaded = false; 

di

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

     isFragmentLoaded = true; 
    } 
else{ 
    } 
} 
+3

ma questo metodo chiama prima su onCreateView – Nepster

0

io tipo O ho lo stesso problema Ho trovato del codice utile su questo sito e lo trasformo.

Il valore minimo per mViewPager.setOffscreenPageLimit (...); è 1, quindi anche se lo cambi a 0 avrai ancora 2 pagine caricate.

prima cosa da fare è creare un static int chiameremo maxPageCount e sovrascrivere FragmentStatePagerAdapter metodo getCount() per restituire maxPageCount:

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

Crea quindi un metodo statico accessibile da qualsiasi parte del programma che permettono di cambiare questo MaxCount:

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

Ora inizializzare maxPageCount a 1. Quando mai si vuole si può aggiungere un'altra pagina. Nel mio caso quando avevo bisogno che l'utente trattasse la pagina corrente prima di generare l'altro. Lo fa e quindi, senza problemi, puoi passare alla pagina successiva.

Spero che aiuti qualcuno.

Problemi correlati