wake-up-neo.net

wie lade ich ein Fragment in ViewPager, wenn es ausgewählt ist?

Ich verwende 3 Fragments innerhalb einer Viewpager, das Problem ist, dass ich große Datenmengen in eine Asynctask und Lader lade. Auf Geräten wie HTC one funktioniert es einwandfrei, auf Low-End-Geräten nimmt es jedoch viel Zeit in Anspruch. Dies liegt hauptsächlich daran, dass ich beim Implementieren der pagerAdapter die Fragmente in eine ArrayList lege. Dadurch werden die Fragmente instanziiert, wenn die Hauptaktivität geladen wird. Was ich brauche ist, dass es nur das erste Fragment (main) "lädt" und wenn der Benutzer Swype, das andere Fragment lädt. es ist eine Möglichkeit, dies zu erreichen? das ist mein pageAdapater

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

    }

} 
12
Javier

Die obige Methode von Sun hat bei mir nicht funktioniert (vielleicht bei Ihnen), aber ich dachte, ich würde meine Bearbeitung seiner Methode auch teilen. Sehr gute Methode übrigens so!

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

Ich werde hier meine Lösung hinzufügen, da ich auf ein ähnliches Problem gestoßen bin. Meine asynchrone Aufgabe hat keine großen Datenmengen geladen, verhindert jedoch unnötige Netzwerkaufrufe. Folgendes habe ich in mein Fragment eingefü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 wird Ihr Fragment geladen, aber Ihre asynchrone Aufgabe wird erst ausgeführt, wenn der Benutzer tatsächlich zum ersten Mal zum Fragment navigiert. Nach der Anzeige wird Ihre asynchrone Aufgabe automatisch zum ersten Mal ausgeführt. Anschließend können Sie über eine Schaltfläche weitere Daten laden oder zum Aktualisieren ziehen. Das obige Fragment befand sich in meinem ViewPager und schien gut zu funktionieren.

10
Sun

Ich komme vielleicht zu spät zur Party, aber hier ist meine Lösung und sie funktioniert wie erwartet. Erstellen Sie in allen untergeordneten Fragmenten eine boolean-Variable:

private boolean loadFragmentExecuted = false;

erstellen Sie in den untergeordneten Fragmenten eine generische Methode mit dem Namen loadFragment und verschieben Sie die gesamte Logik, die Sie in onCreateView hinzugefügt haben, in diese Methode:

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

erstellen Sie in Ihrer PageView-Logik die Fragmente dynamisch wie folgt:

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

stellen Sie dann Ihren Pager-Adapter ein und fügen Sie ein Tablayout hinzu:

//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)
    {
    }
});
0
SolidSnake

Verwenden Sie fragmentStatePageAdapter, wenn Sie viele Seiten haben und diese zerstören möchten, wenn sie nicht sichtbar sind. Es hat ein setMenuVisibility (boolesches menuVisible) implementiert, wenn ein Fragment sichtbar wird. Verwenden Sie dieses.

0

Leicht modifizierte Version, um potenzielle NPE-Probleme zu beheben, die durch einige nicht vollständig initialisierte Ansichten verursacht wurden

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) {
            new Handler().post(() -> {
                makeAsyncRequest();//do your asyn stuffs 
                _hasLoadedOnce = true;
            });
        }
    }
}
0
pjwin