FragmentPagerAdapter avec ViewPager et deux Fragments. Aller au premier à partir de la seconde et mettre à jour le texte de première

Je ne suis pas familier avec FragmentPagerAdapter , donc ce sera une de ces questions que nous (vous) lisez la description de manière critique.

Structure: J'ai un FragmentPagerAdapter (code ci-dessous), qui contiendra deux fragments à la fois. Le premier affiche des extraits de livres et le second une liste de titres de livres.

  • Impossible de normaliser le chemin du fichier 'E: \ WorkSpace \ mapdemo \ app \ build \ intermediates \ mockable-Google Inc.: API Google: 21.jar'
  • L'émulateur Android Cordova a cessé de fonctionner
  • Android supprime l'espace entre les onglets dans le tabwidget
  • Ne peut pas résoudre la méthode 'findViewById (int)'
  • Android-Gradle: un problème est survenu lors de la configuration du projet racine studio Android
  • Webviewglue nativedestroy view
  • But: Je veux atteindre ce qui est décrit dans le titre: l'utilisateur peut naviguer vers le deuxième fragment dans le pager, cliquer sur un titre, puis je souhaite déplacer l'utilisateur vers le premier fragment et indiquer le premier fragment à mettre à jour le texte. Le premier fragment a une méthode triggerRefresh pour cela.

    Code: Je crois que mon problème se produit en raison de la façon dont FragmentPagerAdapter réutilise / crée les Fragments (ce que je ne comprends pas). C'est ma classe:

     static class MyFragmentPagerAdapter extends FragmentPagerAdapter { public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUM_ITEMS; } @Override public Fragment getItem(int position) { switch(position) { case 0: return new ExcerptsFragment(); case 1: return new BookListFragment(); default: throw new IllegalArgumentException("not this many fragments: " + position); } } } 

    Voici comment j'ai créé les membres concernés:

     ViewPager mViewPager = (ViewPager) findViewById(R.id.pager); MyFragmentPagerAdapter mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); mViewPager.setAdapter(mFragmentPagerAdapter); 

    Et c'est ce que j'ai essayé ailleurs dans mon Activité, quand je reçois le rappel des titres de livres Fragment avec le titre sélectionné:

     mViewPager.setCurrentItem(0); // back to excerpts screen page. It's OK. // Here's the problem! How to identify the fragment 0 // to ExcerptsFragment and call its triggerRefresh()?!? 

    Série de problèmes:

    L'appel du getView() l'adaptateur ne fonctionnera pas car il renverra une nouvelle instance de ExcerptsFragment , qui n'est pas celle actuellement attachée (comme prévu, jette l'exception).

    J'ai vu beaucoup de gens ici ( exemple ), juste stocker des fragments dans le getView() . Est-ce correct? Parce qu'en regardant les exemples officiels, cela me semble être un anti-modèle (battre la référence automatique en tenant les objets). Et c'est aussi l'opinion ici et ici (et me paraît bien).

    Aucune suggestion? Je ne serais pas surpris si je ne comprends pas tout cela …

  • Remplacer un personnage par un autre personnage dans une chaîne dans Android?
  • Annotation @Override dans Android
  • L'activité a filtré la fenêtre com.android.internal.policy.impl.PhoneWindow$DecorView@46368a28 qui a été ajouté à l'origine ici
  • Le navigateur Android étend l'image
  • Android Linkify text - Spannable Text in Single Text View - As like Twitter tweet
  • Android: comment faire une belle animation de battement de coeur?
  • 3 Solutions collect form web for “FragmentPagerAdapter avec ViewPager et deux Fragments. Aller au premier à partir de la seconde et mettre à jour le texte de première”

    Avertissement: Bien que cela ait fonctionné parfaitement bien pour moi auparavant, vous devez être conscient des pièges classiques selon le comportement interne et privé . Alors que j'avais écrit des tests qui finiraient par m'avoir averti si la mise en œuvre interne avait changé, je me suis déplacé vers des pâturages plus verts . Et vous devriez aussi. En tant que tel, la valeur de cette question et sa réponse est seulement historique, à mon avis.


    Désolé pour cette question, je pense que c'était l'heure.

    Pour résoudre ce problème, j'ai implémenté cette solution telle quelle. Cela semble fonctionner très bien. Donc, je crois qu'il s'agissait simplement de trouver l'instance de fragment (actuellement jointe) en déterminant comment son ID est nommé. Le lien ci-dessus explique comment il est réalisé.

    J'ai choisi de répondre à ma propre question au lieu de la supprimer parce que je crois que les novices comme moi sur ces téléavertis bénéficieront d'un «scénario réel». La plupart des réponses que j'ai vus parlent le plus de la théorie, qui est la bonne façon BTW … mais sans un véritable exemple pour travailler parfois, certaines personnes comme moi se perdent.

    Quoi qu'il en soit, voici le dernier code dont j'avais besoin (la partie commentée ci-dessus):

     int n = 0; mViewPager.setCurrentItem(n); // in the question I had stopped here. ExcerptsFragment f = (ExcerptsFragment) ContainerActivity.this .getSupportFragmentManager().findFragmentByTag(getFragmentTag(n)); f.triggerRefresh(); // ... below the helper method: used the solution from the link. private String getFragmentTag(int pos){ return "android:switcher:"+R.id.pager+":"+pos; } 

    Donc, j'ai l'impression qu'il s'agit d'une solution robuste, car je ne présente aucune référence aux fragments (risquant ainsi que les références soient obsolètes). J'ai gardé mon propre code au minimum, minimisant ainsi les chances de faire quelque chose de stupide.

    Bien sûr, si vous avez quelque chose à ajouter, pour nous montrer, pour dire ce qui ne va pas en le faisant ou ce qui peut être amélioré, je serai heureux de vous entendre.

    J'ai cherché une solution à ce problème un moment moi-même. Votre approche en principe fonctionne, mais elle va rompre votre code si jamais le code de la création de la marque de fragment dans la mise en œuvre de la classe de base Android change. C'est une dépendance assez désagréable!

    Une approche plus élégante serait de transformer le problème et de garder une instance de votre activité de base dans votre fragment. Mettre en place un setter pour la balise dans votre activité et appeler cela à l'intérieur du fragment lors de la création – la balise est simplement disponible avec getTag ().

    Un exemple d'implémentation peut être trouvé ici .

    J'ai résolu ce problème en utilisant WeakReferences sur les fragments lors de la création. Voir: https://stackoverflow.com/a/23843743/734151

    Si vous trouvez un problème avec cette approche, veuillez commenter.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.