2013-10-21 5 views
11

im Verwenden von 3 Fragmenten in einem Viewpager, das Problem, das Laden großer Daten in Asytask und Loader, in Geräten wie HTC eins funktioniert gut, aber in Low-End-Geräten nehmen eine Menge Zeit . Dies liegt daran, dass, wenn ich den PagerAdapter implementiere, ich die Fragmente in eine ArrayList stelle, so erzwingen die Fragmente die Instabilität, wenn die Hauptaktivität geladen wird. Was ich brauche ist einfach "Laden" das erste Fragment (Haupt) und wenn der Benutzer "swype" das andere Fragment laden. Ist es möglich, dies zu erreichen? das ist meine SeiteAdapterwie laden Fragment in ViewPager nur, wenn es

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

Versuchen Sie pager.setOffscopePageLimit (1); Dies wird ein Fragment auf einmal beibehalten. –

+0

Dies wird in "Speicher" beibehalten, aber es wird das Fragment jedes Mal, wenn die Verwendung Swype. – Javier

+0

Yup .. es wird erfrischen .. –

Antwort

9

Die obige Methode von Sun funktionierte nicht für mich (vielleicht tut es für Sie), aber ich dachte, ich würde meine Bearbeitung seiner Methode auch teilen. Sehr gute Methode übrigens 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

Es hat mir geholfen, Danke zu erklären @Sun ändert sich damit man das leicht verstehen kann. – Irfan

+0

Der Unterschied ist, dass in der Sekunde, wenn @Sun schrieb! IsFragmentVisible. In meinem Fall funktionierte es auch nicht, weil ich die asynchrone Aufgabe brauchte, um zu zeigen, wenn das Fragment sichtbar ist, nicht danach. – IRPdevelop

8

Ich werde hier meine Lösung hinzufügen, da ich auf ein ähnliches Problem gestoßen bin. Meine asynchrone Task hat keine großen Datenmengen geladen, verhindert jedoch unnötige Netzwerkanrufe. Hier ist, was ich in meinem Fragmente hinzugefügt:

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; 
     } 
    } 
} 

Mit dem obigen Code, Ihr Fragment geladen wird, aber Ihre async Aufgabe nicht ausgeführt werden, bis der Benutzer tatsächlich mit dem Fragmente zum ersten Mal scrollt. Sobald die asynchrone Task angezeigt wird, wird sie zum ersten Mal automatisch ausgeführt. Dann können Sie eine Möglichkeit bereitstellen, um mehr Daten über eine Schaltfläche zu laden oder um sie zu aktualisieren. Das obige Fragment war in meinem ViewPager und schien gut zu funktionieren.

+0

Vielen Dank Chef. Sie sparen meine Zeit. Vor zwei Tagen habe ich mein Suchproblem versucht. sein Anruf nächstes Fragment.Vielen vielen Dank –

+0

setUserVisibleHint Ich hatte dies verwendet und für das Verhindern des Vorladens, aber das Problem ist, wenn ich meine async in dieser Methode aufrufen und in postExecute-Methode einige Layout und TextView haben und alle Nullpointer bekommen. –

+0

Es sollte beachtet werden, dass diese setUserVisibleHint vor onCreate aufgerufen wird. Wenn für Ihre Aufgabe ein Verweis auf die Aktivität/den Kontext erforderlich ist, wird eine NPE erstellt. – mwieczorek

0

Verwenden Sie fragmentStatePageAdapter, wenn Sie viele Seiten haben und diese nicht sichtbar löschen möchten. Es hat eine setMenuVisibility (boolean menuVisible) implementiert, wenn das Fragment sichtbar wird, also benutze es.

0

Ich könnte für die Party zu spät kommen, aber hier ist meine Lösung und es funktioniert wie erwartet. In all Ihrem Kind Fragmente erstellen boolean Variable:

private boolean loadFragmentExecuted = false; 

in den Kinder Fragmente erstellen eine generische Methode loadFragment genannt und die gesamte Logik Sie in onCreateView dieser Methode hinzugefügt bewegen:

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

in Ihre Seitenaufruflogik erzeugt die Fragmente dynamisch wie:

//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(); 
} 

dann stellen Sie Ihren Pageradapter ein und befestigen Sie eine ta Blayout damit:

//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) 
    { 
    } 
}); 
Verwandte Themen