web-dev-qa-db-fra.com

FragmentPagerAdapter getItem n'est pas appelé

Je ne suis pas en mesure de réutiliser un fragment dans FragmentPagerAdapter .. À l'aide de la méthode destroyItem (), elle supprime le fragment mais ne s'appelle toujours pas getItem () encore ..

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

Et dans FragmentActivity,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 
108
Kanika

KISS Réponse:

Utilisation simple FragmentStatePagerAdapter au lieu de FragmentPagerAdapter .

J'ai eu la réponse. Premièrement, j'ai pensé à supprimer cette question car je fais une erreur très stupide, mais cette réponse aidera quelqu'un qui fait face au même problème qu'au lieu de FragmentPagerAdapter, utilisez FragmentStatePagerAdapter.

Comme @BlackHatSamurai mentionné dans le commentaire:

Cela fonctionne parce que FragmentStatePagerAdapter détruit comme des fragments qui ne sont pas utilisés. FragmentPagerAdapter ne le fait pas.

280
Kanika

L'utilisation de FragmentStatePagerAdapter n'a pas complètement résolu mon problème. Il s'agissait d'un problème similaire dans le cadre duquel onCreateView n'était pas appelé pour des fragments enfants dans le pageur de vues. Je suis en fait imbriqué ma FragmentPagerAdapter dans une autre Fragment donc la FragmentManager a été partagée par tous et conservant ainsi des instances des anciens fragments. Le correctif consistait plutôt à alimenter une instance de getChildFragmentManager au constructeur de FragmentPagerAdapter dans mon fragment hôte. Quelque chose comme...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

La méthode getChildFragmentManager() est accessible via un fragment, ce qui a fonctionné pour moi car elle renvoie une variable privée FragmentManager pour ce fragment spécifiquement pour les situations dans lesquelles des fragments imbriqués sont nécessaires. J'espère que cela aidera quelqu'un qui pourrait avoir le même problème que j'étais !!

  • Cependant, gardez à l'esprit que pour utiliser getChildFragmentManager(), la version minimale de votre API doit être au moins 17 (4.2), de sorte que cela risque de vous faire perdre la vie. Bien sûr, si vous utilisez des fragments de la bibliothèque de support technique v4, tout devrait bien se passer.
141
Jraco11

Il existe deux scénarios différents: 1.) Vous avez la même présentation pour chaque pager: Dans ce cas, il sera préférable d’étendre votre adaptateur personnalisé par PagerAdapter et renvoyer une seule mise en page.

2.) Vous avez une mise en page différente pour chaque pageur: Dans ce cas, il sera préférable d’étendre votre adaptateur personnalisé par FragmentStatePagerAdapter et renvoient différents fragmets pour chaque pager.

2
Maddy

J'ai fait ce que @kanika et @ Jraco11 avaient posté mais j'avais toujours le problème. 

Ainsi, après beaucoup de changements, j'en ai trouvé un qui fonctionnait pour moi et j'ai ajouté à mon FragmentPagerAdapter le code suivant:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

Selon ce que j'ai lu, getItemPosition est utilisé pour informer le ViewPager s'il doit ou non actualiser un élément, et pour éviter les mises à jour si les éléments aux positions visibles n'ont pas changé. 

2
Jorge Casariego

J'ai trouvé que le fait de définir un auditeur sur la disposition des onglets empêchait l'appel, probablement parce qu'ils n'avaient de la place que pour un auditeur sur tabLayout.setOnTabSelectedListener au lieu d'un tableau d'auditeurs.

0
Oliver Dixon

la méthode getItem() est utilisée uniquement pour créer de nouveaux éléments. Une fois qu'ils ont créé, cette méthode ne sera pas appelée. Si vous devez obtenir un article dont la devise est utilisée par l'adaptateur, utilisez cette méthode:

pagerAdapter.instantiateItem(viewPager, TAB_POS)
0
B-GangsteR