wake-up-neo.net

Ersetzen Sie das Fragment durch ein anderes Fragment in ViewPager

Ich verwende einen ViewPager zusammen mit einem FragmentPagerAdapter, um drei verschiedene Fragmente zu hosten

[Fragment1][Fragment2][Fragment3]

Was ich zu erreichen versuche ist, Fragment1 erfolgreich durch ein ganz neues Fragment, Fragment4, zu ersetzen, wenn eine bestimmte Aufgabe erfolgreich ist.

Wenn ich benutze ..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, fragment4);
transaction.commit();

Das Fragment wird schön ersetzt und Fragment4 wird anstelle von Fragment1 angezeigt. Sobald ich den ganzen Weg zu Fragment3 und dann zu Fragment4 zurückgestoßen bin, hat Fragment1 ein Comeback gemacht.

Dann wieder, wenn ich benutze ..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment1);
transaction.commit();

..Fragment1 wird entfernt und wenn ich zurückkomme, ist Fragment4 da. Das Problem bei dieser Lösung ist also, dass ich keinen Weg finden konnte, Fragment4 sofort anzuzeigen, wenn Fragment1 entfernt wird, selbst wenn ich Folgendes versucht habe:

transaction.add(fragment4);
transaction.show(fragment4);

Und so sieht meine FragmentPagerAdapter-Implementierung im Moment aus, ohne Transaktionsverwaltung :

public static class PagerAdapter extends FragmentPagerAdapter {

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

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

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = null;

        switch (position) {
        case 0:
            fragment = Fragment1.newInstance(context_);
            break;

        case 1:
            fragment = Fragment2.newInstance(context_);
            break;

        case 2:
            fragment = Fragment3.newInstance(context_);
            break;

        default:
            break;
        }

        return fragment;
    }
}

Bearbeiten.

Es scheint also, dass ich mit meiner Frage nicht völlig klar war. Ich entschloss mich, alle Spaghetti, die ich zuvor kreiert hatte, zu entfernen, und versuchte zu erklären, dass ich sie ausgeschaltet hatte (siehe Fettdruck oben).

Wie auch immer, hier ist ziemlich genau das, was ich in getItem () versucht habe:

@Override
public Fragment getItem(int position) {

    Fragment fragment = null;

    switch (position) {
    case 0:

        if (!app.isUserLoggedIn) {
            if (loginFragment_ == null) {
                loginFragment_ = LoginFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (logoutFragment_ != null) {
                    transaction_.remove(logoutFragment_);
                    logoutFragment_ = null;
                }

                transaction_.add(loginFragment_, "login");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("login") == null)
                fragment = LoginFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("login");

        } else {
            if (logoutFragment_ == null) {                      
                logoutFragment_ = LogoutFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (loginFragment_ != null) {
                    transaction_.remove(loginFragment_);
                    loginFragment_ = null;
                }

                transaction_.add(logoutFragment_, "logout");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("logout") == null)
                fragment = LogoutFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("logout");
        }
        break;

    case 1:
        fragment = HomeFragment.newInstance(context_);
        break;

    case 2:
        fragment = RegisterFragment.newInstance(context_);
        break;

    default:
        break;
    }

    return fragment;
}

Mit diesem Code werde ich nichts getan, aber wenn jemand sieht, was ich falsch mache und mich in die richtige Richtung weisen möchte, würde ich das sehr begrüßen!

23
velu

Versuchen Sie es mit FragmentStatePagerAdapter 

http://Android-developers.blogspot.com/2011_08_01_archive.html

wenn Sie durch die Ansicht streichen (auch wenn Sie getitem aufrufen), wird das Fragment entfernt, sodass Sie sie nicht explizit selbst entfernen müssen.

Ich hatte das gleiche Problem, das für mich funktioniert.

Ich versuche Ihren Code und entferne den if (fragment!=null)-Block, und es funktioniert.

10
GAO-tsukai

Wie Maurycy gesagt hat, müssen Sie mAdapter.notifyDataSetChanged() anrufen, wenn Sie dem ViewPager mitteilen möchten, dass die Fragmente ersetzt wurden. Sie müssen jedoch auch die abstrakte Funktion getItemPosition() in Ihrem Adapter überschreiben und POSITION_NONE zurückgeben, wenn sie mit einem alten, als verborgenen Fragment als Argument aufgerufen wird. Andernfalls behält ViewPager alle aktuellen Fragmente bei.

Weitere Informationen und Beispielcode finden Sie unter diese Antwort auf eine bezogene Frage .

3
wize

Hey, ich habe dieses Problem gelöst, indem ich eine Liste in meinem FragmentPagerAdapter verwende, um die verschiedenen Fragmente zu bearbeiten, und dann ist mein getItem so ...

    public void addScreen(String tag, Class<?> clss, Bundle args){
        if(clss!=null){
            TabInfo info = new TabInfo(tag, clss, args);
            screens.add(info);
        }
    }
@Override
    public Fragment getItem(int position) {
        TabInfo info = screens.get(position);
        return Fragment.instantiate(context, info.clss.getName(), info.args);
    }

Ich entferne/fügte programmgesteuert die Listenelemente (Fragmente) hinzu und ordne sie dann an. Dann rufe ich den Handler auf

mAdapter.notifyDataSetChanged()
0
Maurycy

Bitte sehen Sie meine Antwort zu einer ähnlichen Frage zum Einfügen/Ersetzen von Registerkarten mit einer ViewPager und FragmentPagerAdapter.

0
jfritz42

Setzen Sie offScreenPageLimit auf 5 (oder basierend auf Ihrer Usecase), um ein erneutes Laden des Fragments zu vermeiden, sodass das ersetzte Fragment erhalten bleibt, anstatt beim Wischen erneut geladen zu werden.

    mViewPager.setOffscreenPageLimit(5);
0
Shangeeth Sivan

Sollte Ihre getItem-Anweisung unter bestimmten Umständen nicht fragment4 für case 0 zurückgeben?

0
Sashi Kolli