FragmentPagerAdapter getItem n'est pas appelé

Je ne suis pas en mesure de réutiliser fragment dans FragmentPagerAdapter.. En utilisant la méthode destroyItem (), il supprime le fragment mais ne s'appelle toujours pas getItem ()..Il n'y a que 2-3 Images donc j'utilise FragmentPagerAdapter au lieu de FragmentStatePagerAdapter..

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)); 
101
demandé sur michoprogrammer 2012-09-25 15:21:15

6 réponses

KISS Answer:

utilisation Simple FragmentStatePagerAdapter au lieu de FragmentPagerAdapter .

j'ai eu la réponse.. Tout d'abord , 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 que FragmentPagerAdapter , utiliser FragmentStatePagerAdapter .

comme @BlackHatSamurai l'a mentionné dans le commentaire:

la raison pour laquelle cela fonctionne est parce que FragmentStatePagerAdapter détruit comme des Fragments qui ne sont pas utilisés. FragmentPagerAdapter ne fonctionne pas.

271
répondu Kanika 2016-09-25 15:38:53

utilisant un FragmentStatePagerAdapter n'a pas entièrement corrigé mon problème qui était un problème similaire où onCreateView n'a pas été appelé pour des fragments d'enfant dans le pager de vue. Je suis en fait nichant mon FragmentPagerAdapter à l'intérieur d'un autre Fragment donc le FragmentManager a été partagé dans chacun d'eux et donc en retenant des instances des vieux fragments. Le correctif était plutôt d'alimenter une instance du getChildFragmentManager au constructeur du FragmentPagerAdapter dans mon hôte fragment. Quelque chose comme...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

la méthode getChildFragmentManager() est accessible via un fragment et cela a fonctionné pour moi car il retourne un FragmentManager privé pour ce fragment spécifiquement pour les situations dans lesquelles des fragments de nidification est nécessaire. J'espère que ça aidera quelqu'un qui a peut-être le même problème que moi!!

  • gardez à l'esprit cependant d'utiliser getChildFragmentManager() votre version API minimum doit être au moins 17 (4.2) , donc cela peut jeter une clé dans vos rapports. Bien sûr, si vous utilisez des fragments de la bibliothèque de soutien v4 vous devriez être d'accord.
130
répondu Jraco11 2017-09-03 12:35:03

Il y a deux scénarios différents : 1.) Vous avez la même mise en page pour chaque pager : Dans ce cas, il est préférable d'étendre votre adaptateur personnalisé par PagerAdapter et retourner une mise en page unique.

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

2
répondu Maddy 2015-01-21 09:37:23

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

donc, après beaucoup de changements, j'ai trouvé un qui a fonctionné pour moi et a été ajouté à mon FragmentPagerAdapter le code suivant:

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

selon ce que j'ai lu, getitemportion est utilisé pour notifier le ViewPager si oui ou non rafraîchir un élément, et d'éviter les mises à jour si les éléments aux positions visibles n'ont pas modifié.

2
répondu Jorge Casariego 2016-04-28 02:39:41

Remplacer long getItemId (int position)

FragmentPagerAdapter cache les fragments qu'il crée en utilisant getItem . Je faisais face à la même question - même après avoir appelé notifyDataSetChanged() getItem n'a pas été appelé.

il s'agit en fait d'une fonctionnalité et non d'un bogue. Vous devez remplacer getItemId pour pouvoir réutiliser correctement vos fragments. Puisque vous retirez des fragments, vos positions changent. Comme mentionné dans la docs:

long getItemId (int position)

renvoie un identificateur unique pour l'article à la position donnée.

l'implémentation par défaut renvoie la position donnée. Les sous-classes devraient remplacer cette méthode si la position des éléments peut changer.

il suffit de fournir un identifiant unique à chaque fragment et vous avez terminé.

utilisant un FragementStatePagerAdapter ou le retour POSITION_NONE dans int getItemPosition (Object object) est erroné. Vous ne recevrez pas de mise en cache.

1
répondu vedant 2018-02-16 15:17:26

j'ai trouvé que la mise en place d'un listener sur l'onglet-layout a arrêté cela d'être appelé, probablement parce qu'ils ont seulement l'espace pour un listener sur tabLayout.setOnTabSelectedListener au lieu d'un tableau d'auditeurs.

0
répondu Oliver Dixon 2016-02-04 07:19:29