129 votes

FragmentPagerAdapter getItem n'est pas appelé

Je ne suis pas en mesure de réutiliser le fragment dans FragmentPagerAdapter . En utilisant la méthode destroyItem(), il supprime le fragment mais n'appelle toujours pas getItem() à nouveau 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));

3 votes

Y a-t-il une raison particulière pour laquelle vous avez annulé destroyItem() ? Ce n'est pas nécessaire.

0 votes

Pour initialiser à nouveau, utilisez FragmentStatePagerAdapter et appelez également lorsque vous le surchargez super.destroyItem(container, position, object) ;

317voto

Kanika Points 2522

Réponse KISS :

Utilisation simple FragmentStatePagerAdapter au lieu de FragmentPagerAdapter .

J'ai eu la réponse J'ai d'abord pensé à supprimer cette question car je fais une erreur très bête, mais cette réponse aidera quelqu'un qui est confronté au même problème que moi. FragmentPagerAdapter utiliser FragmentStatePagerAdapter .

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

La raison pour laquelle cela fonctionne est que FragmentStatePagerAdapter détruit comme des fragments qui ne sont pas utilisés. FragmentPagerAdapter ne le fait pas.

0 votes

Merci beaucoup. Votre réponse m'a beaucoup aidé.

2 votes

Je déteste être un autre post "moi aussi", mais oui >.< Merci de ne pas avoir supprimé la question.

0 votes

Je pense que les fragments sont déposés dans une poubelle de recyclage pour une utilisation ultérieure lorsqu'ils sont détruits, de sorte que lorsqu'un nouveau pager est créé, il est rempli de fragments recyclés. Cela pourrait probablement être corrigé en ne mettant pas de code spécifique au contenu dans l'appel getItem (tel que le réglage d'une image basée sur les variables du pager, les tableaux, etc.)

173voto

Jraco11 Points 3363

Utilisation d'un FragmentStatePagerAdapter n'a pas entièrement résolu mon problème qui était un problème similaire où onCreateView n'était pas appelé pour les fragments enfants dans le pager de la vue. Je suis en fait emboîter mes FragmentPagerAdapter à l'intérieur d'un autre Fragment par conséquent, le FragmentManager a été partagée par tous et a ainsi permis de conserver des instances des anciens fragments. La solution consistait à alimenter une instance de la classe getChildFragmentManager au constructeur de la FragmentPagerAdapter dans mon fragment d'hôte. Quelque chose comme...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

El getChildFragmentManager() est accessible via un fragment et cela a fonctionné pour moi parce qu'elle renvoie une méthode privée FragmentManager pour ce fragment, spécifiquement pour les situations dans lesquelles l'imbrication des fragments est nécessaire. J'espère que cela aidera quelqu'un qui pourrait avoir le même problème que moi !

  • N'oubliez pas cependant d'utiliser getChildFragmentManager() la version minimale de votre API doit être d'au moins 17 (4.2) donc cela peut vous mettre des bâtons dans les roues. Bien sûr, si vous utilisez des fragments de la bibliothèque de support v4, tout devrait bien se passer.

10voto

vedant1811 Points 658

Remplacer long getItemId (int position)

FragmentPagerAdapter met en cache les fragments qu'il crée en utilisant getItem . J'étais confronté au même problème - 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 bug. Vous devez remplacer getItemId afin que vous puissiez réutiliser correctement vos fragments. Comme vous supprimez des fragments, vos positions changent. Comme mentionné dans les docs :

long getItemId (int position)

Renvoie un identifiant unique pour l'élément à la position donnée.

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

Il suffit de fournir un identifiant unique à chaque fragment et le tour est joué.

Utilisation d'un FragementStatePagerAdapter ou en retournant POSITION_NONE en int getItemPosition (Object object) a tort. Vous n'obtiendrez pas de mise en cache.

5voto

casariegj Points 61

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

Ainsi, après de nombreuses modifications, j'ai trouvé celle qui me convenait et j'ai ajouté à mon FragmentPagerAdapter le code suivant :

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

D'après ce que j'ai lu, getItemPosition est utilisé pour notifier le ViewPager de rafraîchir ou non un élément, et d'éviter les mises à jour si les éléments aux positions visibles n'ont pas changé.

4voto

B-GangsteR Points 1073

Méthode getItem() est utilisé uniquement pour créer de nouveaux éléments. Une fois qu'ils ont été créés, cette méthode ne sera pas appelée. Si vous avez besoin d'obtenir un élément qui est actuellement utilisé par l'adaptateur, utilisez cette méthode :

pagerAdapter.instantiateItem(viewPager, TAB_POS)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X