web-dev-qa-db-fra.com

Remplacer le fragment par un autre fragment dans ViewPager

J'utilise un ViewPager avec un FragmentPagerAdapter pour héberger trois fragments différents

[Fragment1][Fragment2][Fragment3]

Ce que j'essaie de faire est de remplacer avec succès Fragment1 par un tout nouveau fragment, Fragment4, si une tâche spécifique réussit.

Quand j'utilise ..

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

..le fragment est joliment remplacé et Fragment4 est affiché à la place de Fragment1. Bien que dès que j'ai glissé jusqu'à Fragment3 puis à Fragment4, Fragment1 a fait un retour.

Là encore, si j'utilise ..

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

Fragment1 est enlevé et quand je reviens, Fragment4 est là. Le problème avec cette solution est que je ne pouvais pas trouver un moyen de montrer immédiatement que Fragment4 car Fragment1 est supprimé, même si j'ai essayé:

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

Et voici à quoi ressemble mon implémentation FragmentPagerAdapter pour le moment, sans aucune gestion de transaction :

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

Modifier.

Il semble donc que ma question ne soit pas tout à fait claire. J'ai décidé de supprimer tous les spaghettis que j'avais réussi à créer plus tôt et j'ai essayé de déclarer que je les avais laissés (voir le texte en gras ci-dessus).

Quoi qu'il en soit, voici à peu près ce que j'ai essayé de faire dans getItem ():

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

Avec ce code, je ne fais rien, mais si quelqu'un voyait ce que je faisais mal et voudrait me diriger dans la bonne direction, je l'apprécierais beaucoup!

23
velu

Essayez d'utiliser FragmentStatePagerAdapter 

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

coz il supprimera le fragment lorsque vous glissez dans la vue (également lorsque vous appelez getitem), vous n'avez donc pas besoin de les supprimer explicitement vous-même.

J'ai le même problème, ça marche pour moi.

J'essaie votre code et supprime le bloc if (fragment!=null) et cela fonctionne.

10
GAO-tsukai

Comme Maurycy l'a dit, vous devez appeler mAdapter.notifyDataSetChanged() chaque fois que vous souhaitez informer le ViewPager que les fragments ont été remplacés. Cependant, vous devez également redéfinir la fonction abstraite getItemPosition() dans votre adaptateur et renvoyer POSITION_NONE lorsqu'il est appelé avec un ancien fragment à masquer en tant qu'argument. Sinon, ViewPager conservera tous les fragments actuels.

Pour plus d'informations et un exemple de code, voir this answer à une question associée .

3
wize

Hey, j'ai résolu ce problème en utilisant une liste dans mon FragmentPagerAdapter pour gérer les différents fragments, puis mon getItem est comme si ....

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

Je supprime ensuite/ajoute/réorganise les éléments de la liste (fragments) par programme, puis appelle le gestionnaire

mAdapter.notifyDataSetChanged()
0
Maurycy

Veuillez consulter ma réponse à une question similaire sur la manière d’insérer/remplacer des tabulations par ViewPager et FragmentPagerAdapter.

0
jfritz42

Essayez de définir offScreenPageLimit sur 5 (ou sur la base de votre cas d'utilisation) pour éviter de recharger le fragment afin que ce que vous ayez remplacé reste au lieu d'être rechargé lorsque vous faites glisser votre doigt.

    mViewPager.setOffscreenPageLimit(5);
0
Shangeeth Sivan

Votre instruction getItem ne devrait-elle pas renvoyer fragment4 pour case 0 dans certaines circonstances?

0
Sashi Kolli