2013-10-21 21 views
11

im utilizzando 3 frammenti all'interno di un Viewpager, il problema è il caricamento dei big data in asytask e caricatori, in dispositivi come HTC uno funziona bene, tuttavia nei dispositivi di fascia bassa ci vuole un sacco di tempo . Questo perché principalmente quando implemento il pagerAdapter inserisco i Fragments all'interno di un arrayList, questo impone ai frammenti di instaziare quando viene caricata l'attività principale. Quello di cui ho bisogno è semplicemente "caricare" il primo frammento (main) e quando l'utente "swype" carica l'altro frammento. è un modo per raggiungere questo? questa è la mia paginaAdapatercome caricare il frammento in ViewPager solo quando è selezionato

public class PagerAdapter extends FragmentPagerAdapter { 

    private final ArrayList<Fragment> mFragments = new ArrayList<Fragment>(); 
    // private final ArrayList<String> titulos = new ArrayList<String>(); 

    // private int NUM_PAGES =0; 
    public PagerAdapter(FragmentManager manager,int num_pages) { 
     super(manager); 
    // this.NUM_PAGES = num_pages; 
    } 


    public void addFragment(Fragment fragment,String title) { 
     mFragments.add(fragment); 
      notifyDataSetChanged(); 
    } 

    @Override 
    public int getCount() { 
     //return NUM_PAGES; 
     return mFragments.size(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mFragments.get(position); 

    } 

} 
+0

Prova pager.setOffscreenPageLimit (1); Ciò manterrà un frammento alla volta. –

+0

ciò manterrà in "memoria" uno, tuttavia creerà il frammento ogni volta che si usa swype. – Javier

+0

Sì .. aggiornerà .. –

risposta

9

Il metodo sopra riportato da Sun non ha funzionato per me (forse lo fa per te), ma ho pensato di condividere anche il mio metodo di modifica. Ottimo metodo dal modo in cui Sun!

private boolean _hasLoadedOnce= false; // your boolean field 

@Override 
public void setUserVisibleHint(boolean isFragmentVisible_) { 
    super.setUserVisibleHint(true); 


    if (this.isVisible()) { 
     // we check that the fragment is becoming visible 
     if (isFragmentVisible_ && !_hasLoadedOnce) { 
      new NetCheck().execute(); 
      _hasLoadedOnce = true; 
     } 
    } 
} 
+0

Mi ha aiutato, grazie, spiegare le modifiche di @Sun in modo che si possa capire facilmente. – Irfan

+0

La differenza è che nel secondo se, @Sun ha scritto! IsFragmentVisible. Nel mio caso non funzionava neanche perché avevo bisogno del task asincrono da eseguire quando il frammento è visibile, non dopo. – IRPdevelop

8

Sto per aggiungere la mia soluzione qui poiché ho affrontato un problema simile. Il mio compito asincrono non stava caricando enormi quantità di dati, ma impedisce chiamate di rete non necessarie. Ecco quello che ho aggiunto nella mia Frammento:

private boolean _hasLoadedOnce= false; // your boolean field 

@Override 
public void setUserVisibleHint(boolean isFragmentVisible_) { 
    super.setUserVisibleHint(isVisibleToUser); 


    if (this.isVisible()) { 
     // we check that the fragment is becoming visible 
     if (!isFragmentVisible_ && !_hasLoadedOnce) { 
      //run your async task here since the user has just focused on your fragment 
      _hasLoadedOnce = true; 
     } 
    } 
} 

Con il codice precedente, il vostro Frammento sarà caricato, ma il vostro compito asincrona non verrà eseguita finché l'utente in realtà scorre al frammento per la prima volta. Una volta visualizzato, l'attività asincrona verrà eseguita automaticamente per la prima volta. Quindi puoi fornire un modo per caricare più dati tramite un pulsante o tirare per aggiornare. Il frammento di cui sopra era nel mio ViewPager e sembrava funzionare bene.

+0

Grazie capo. Mi hai salvato il tempo. Ultimi due giorni stavo provando il mio problema di ricerca. chiama il prossimo frammento.Molte molte grazie –

+0

setUserVisibleHint avevo usato questo e lavorando per prevenire il precaricamento, ma il problema è quando chiamo il mio async in questo metodo e nel metodo postExecute hanno alcuni layout e TextView e tutti stanno ottenendo nullpointer. –

+0

Va notato che questo setUserVisibleHint viene chiamato prima di onCreate. Se la tua attività richiede un riferimento all'attività/contesto, questo produrrà un NPE. – mwieczorek

0

Utilizzare fragmentStatePageAdapter se si dispone di molte pagine e si desidera distruggerle quando non sono visibili. Ha implementato una setMenuVisibility (boolean menuVisible) quando il frammento diventa visibile, quindi usalo.

0

Potrei essere in ritardo per la festa ma ecco la mia soluzione e funziona come previsto. In tutti i frammenti bambino creare una variabile boolean:

private boolean loadFragmentExecuted = false; 

nei frammenti bambino creare un metodo generico chiamato loadFragment e spostare tutta la logica si è aggiunto in onCreateView a tale metodo:

public void loadFragment() 
{ 
    if(!loadFragmentExecuted) 
    { 
     //Add your logic to manipulate the UI or load data etc... 
     loadFragmentExecuted = true; 
    } 
} 

in la logica della visualizzazione di pagina crea i frammenti in modo dinamico come:

//add the fragment 
String fragmentName = "com.something." + fragmentId; 

//check if the class exists 
try 
{ 
    Class myFragmentClass = Class.forName(fragmentName); 
    Fragment myFragment = (Fragment) myFragmentClass.newInstance(); 
    mFragments.add(myFragment); 
} 
catch (ClassNotFoundException e) 
{ 
    e.printStackTrace(); 
} 
catch (IllegalAccessException e) 
{ 
    e.printStackTrace(); 
} 
catch (InstantiationException e) 
{ 
    e.printStackTrace(); 
} 

quindi impostare l'adattatore per cercapersone e allegare un ta blayout with it:

//set our pager adapter that contains different fragments 
mPagerAdapter = new BasePagerAdapter(mFragmentManager, mFragments); 

//link the adapter to the viewpager 
mViewPager.setAdapter(mPagerAdapter); 

//cache fragments 
int limit = (mPagerAdapter.getCount() > 0 ? mPagerAdapter.getCount() : 1); 
mViewPager.setOffscreenPageLimit(limit); 

//add the page listner to the viewPager and link it to the tabLayout 
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout)); 

//on tab selected select current viewpager item 
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() 
{ 
    @Override 
    public void onTabSelected(TabLayout.Tab tab) 
    { 
     mViewPager.setCurrentItem(tab.getPosition()); 

     //get fragment for the selected tab 
     Fragment f = mPagerAdapter.getItem(tab.getPosition()); 

     //load the content of the fragment 
     try 
     { 
      Class c = f.getClass(); 
      Method loadFragment = c.getMethod("loadFragment"); 
      loadFragment.invoke(f); 
     } 
     catch (IllegalAccessException e){} 
     catch (InvocationTargetException e){} 
     catch (NoSuchMethodException e){} 
    } 

    @Override 
    public void onTabUnselected(TabLayout.Tab tab) 
    { 
    } 

    @Override 
    public void onTabReselected(TabLayout.Tab tab) 
    { 
    } 
}); 
Problemi correlati