Le nouveau code du du fragment [PlaceholderFragment] est le suivant. Il fonctionne quelque soit l'adjacence donnée aux fragments (1, partielle, totale) : 1. package exemples.android; 2. 3. import android.support.v4.app.Fragment; 4. import android.util.Log; 5. import android.widget.TextView; 6. import org.androidannotations.annotations.AfterViews; 7. import org.androidannotations.annotations.EFragment; 8. import org.androidannotations.annotations.ViewById; 9.
10. // un fragment est une vue affichée par un conteneur de fragments 11. @EFragment(R.layout.fragment_main)
12. publicclass PlaceholderFragment extends Fragment { 13.
14. // composant de l'interface visuelle
15. @ViewById(R.id.section_label) 16. protected TextView textViewInfo; 17. // data
18. private boolean afterViewsDone = false; 19. private boolean initDone = false; 20. private String text;
21. private boolean isVisibleToUser = false; 22. private boolean updateDone = false; 23. private int numVisit = 0;
24.
25. // n° de fragment
26. private staticfinal String ARG_SECTION_NUMBER = "section_number"; 27.
28. // constructeur
29. public PlaceholderFragment() {
30. Log.d("PlaceholderFragment", "constructor"); 31. }
32. 33.
34. @AfterViews
40. if (!initDone) { 41. // texte initial
42. text = getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)); 43. // init done
44. initDone = true; 45. }
46. // affichage texte courant
47. textViewInfo.setText(text); 48. }
49. 50.
51. @Override
52. publicvoid setUserVisibleHint(boolean isVisibleToUser) {
53. ...
54. } 55.
56. @Override
57. publicvoid onDestroyView() { 58. ...
59. } 60.
61. @Override
62. publicvoid onResume() {
63. ...
64. } 65.
66. // update fragment
67. publicvoid update() {
68. // le travail à faire dépend du n° de la visite
69. if (numVisit > 1) { 70. // log
71. Log.d("PlaceholderFragment", String.format("update %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos())); 72. // texte modifié
73. textViewInfo.setText(String.format("%s update(%s)", text, (numVisit - 1))); 74. }
75. } 76.
77. // infos locales pour logs
78. private String getInfos() {
79. return String.format("numVisit=%s, afterViewsDone=%s, isVisibleToUser=%s, initDone=%s, updateDone=%s", numVisit, afterViewsDone, isVisibleToUser, initDone, updateDone);
80. } 81. }
• lignes 34-48 : la méthode [@AfterViews] est susceptible d'être exécutée plusieurs fois. On s'en servait pour initialiser le
texte du fragment (ligne 42). On le fait toujours mais pour ne le faire qu'une fois, on gère un booléen [initDone] (ligne 44) pour indiquer que l'initialisation a été faite et qu'elle n'est pas à refaire ;
• lignes 56-59 : nous introduisons la méthode [onDestroyView] pour noter le fait que la prochaine fois que le fragment va
être réaffiché, son cycle de vie va être réexécuté ;
• les logs ont montré que deux méthodes peuvent s'exécuter après la méthode [@AfterViews] : les méthodes [setUserVisibleHint] et [onResume]. La méthode [onResume] n'est exécutée que lorsque le cycle de vie du fragment est exécuté. La méthode [setUserVisibleHint] elle, n'est pas toujours exécutée après la méthode [@AfterViews]. Les logs ont montré qu'au moins l'une des deux est exécutée après la méthode [@AfterViews]. Les logs n'ont jamais montré que les deux pouvaient être exécutées ensemble après la méthode [@AfterViews]. C'est soit l'une, soit l'autre. Par précaution, on positionnera un booléen [updateDone] lorsqu'une mise à jour a été faite ;
Les méthodes [setUserVisibleHint] et [onResume] sont les suivantes : 1. // data
2. private boolean afterViewsDone = false; 3. private boolean initDone = false; 4. private String text;
5. private boolean isVisibleToUser = false; 6. private boolean updateDone = false; 7. private int numVisit = 0;
8.
9. @Override
10. public void setUserVisibleHint(boolean isVisibleToUser) { 11. // parent
12. super.setUserVisibleHint(isVisibleToUser); 13. // mémoire
14. this.isVisibleToUser = isVisibleToUser; 15. // log
16. Log.d("PlaceholderFragment", String.format("setUserVisibleHint %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos())); 17. // nombre de visites 18. if (isVisibleToUser) { 19. // incrément 20. numVisit++; 21. // update fragment
22. if (afterViewsDone && !updateDone) { 23. update();
24. updateDone = true; 25. }
26. } else {
27. // le fragment va être caché
28. updateDone = false; 29. }
30. } 31.
32. @Override
33. public void onResume() { 34. // parent
35. super.onResume(); 36. // log
37. Log.d("PlaceholderFragment", String.format("onResume %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos()));
38. // update
39. if (isVisibleToUser && !updateDone) { 40. update();
41. updateDone = true; 42. }
43. }
• ligne 14 : on mémorise l'état visible ou non du fragment ;
• lignes 22-25 : si le fragment est visible et que la méthode [@AfterViews] a été exécutée, la méthode [update] est exécutée
et le booléen [updateDone] passé à true ;
• lignes 26-28 : si le fragment va être caché, on remet le booléen [updateDone] à false. Il nous faut en effet un événement
pour réinitialiser à false le booléen [updateDone] mis à true dès que la méthode [update] est appelée afin que de nouvelles mises à jour puissent se faire. Nous utilisons le fait que le fragment n'est plus visible pour le faire. Lorsqu'il redeviendra visible, la mise à jour du fragment devra se faire de nouveau ;
• lignes 32-42 : les logs montrent que selon l'adjacence choisie pour les fragments, la méthode [onResume] peut s'exécuter
alors que le fragment n'est pas visible. S'il n'est pas visible, on ne fait pas la mise à jour (ligne 39) et comme on l'a fait pour [setMenuVisibility], on gère le booléen [updateDone].
Enfin, la méthode [onDestroyView] est la suivante : 1. @Override
2. public void onDestroyView() { 3. // parent
4. super.onDestroyView(); 5. // mise à jour indicateur
6. afterViewsDone = false; 7. // log
8. Log.d("PlaceholderFragment", String.format("onDestroyView %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos()));
9. }
La méthode [onDestroyView] est exécutée lorsqu'un cycle de vie du fragment prend fin. Un autre cycle pourra reprendre ultérieurement.
• ligne 6 : la méthode [onDestroyView] supprime tout lien avec la vue attachée au fragment. Il sera recréé au prochain cycle
de vie du fragment. Pour l'instant, il nous faut mettre le booléen [afterViews] à false, pour indiquer que le lien avec la vue n'existe plus ;
Nous allons exécuter l'application avec 5 fragments ayant une adjacence de 2. Les modifications sont faites dans [MainActivity] : 1. // nombre de fragments
2. private final int FRAGMENTS_COUNT = 5; 3. // adjacence des fragments
4. private final int OFF_SCREEN_PAGE_LIMIT=2; 5.
6.
7. // le gestionnaire de fragments
8. private SectionsPagerAdapter mSectionsPagerAdapter; 9.
10. @AfterViews
11. protected void afterViews() {
12. Log.d("MainActivity", "afterViews"); 13.
14. ....
15.
16. // offset des fragments
17. mViewPager.setOffscreenPageLimit(OFF_SCREEN_PAGE_LIMIT); 18.
19. ...
20. }
Les logs au démarrage sont les suivants :
1. 05-31 06:23:07.015 32551-32551/exemples.android D/MainActivity: constructor 2. 05-31 06:23:07.041 32551-32551/exemples.android D/MainActivity: afterViews 3. 05-31 06:23:07.050 32551-32551/exemples.android D/PlaceholderFragment: constructor 4. 05-31 06:23:07.053 32551-32551/exemples.android D/PlaceholderFragment: constructor 5. 05-31 06:23:07.053 32551-32551/exemples.android D/PlaceholderFragment: constructor 6. 05-31 06:23:07.053 32551-32551/exemples.android D/PlaceholderFragment: constructor 7. 05-31 06:23:07.053 32551-32551/exemples.android D/PlaceholderFragment: constructor 8. 05-31 06:23:07.278 32551-32551/exemples.android D/MainActivity: getItem[0]
9. 05-31 06:23:07.278 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
13. 05-31 06:23:07.278 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
14. 05-31 06:23:07.278 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=true, initDone=false, updateDone=false
15. 05-31 06:23:07.280 32551-32551/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
16. 05-31 06:23:07.291 32551-32551/exemples.android D/PlaceholderFragment: afterViews 3 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
17. 05-31 06:23:07.294 32551-32551/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=false, updateDone=false
18. 05-31 06:23:07.295 32551-32551/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
19. 05-31 06:23:07.295 32551-32551/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
20. 05-31 06:23:07.295 32551-32551/exemples.android D/PlaceholderFragment: onResume 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
21. 05-31 06:23:07.798 32551-32551/exemples.android D/menu: création menu en cours
• lignes 8, 10, 12 : le conteneur de fragments réclame tous les fragments adjacents au fragment 1 ;
• lignes 9, 11, 13 : la méthode [setUserVisibleHint] de ces fragments est exécutée avec [visibleToUser] à false ;
• ligne 14 : la méthode [setUserVisibleHint] du fragment 1 est exécutée avec [visibleToUser] à true ;
• lignes 15-17 : la méthode [afterViews] des 3 segments adjacents est appelée. On voit donc ici un cas où cette méthode est
appelée après qu'un fragment soit devenu visible (le fragment 1 ligne 14) ;
• lignes 18-20 : la méthode [onResume] des 3 segments adjacents est appelée ;
On passe de l'onglet 1 à l'onglet 2 :
1. 05-31 06:52:36.132 32551-32551/exemples.android D/MainActivity: getItem[3]
2. 05-31 06:52:36.132 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
3. 05-31 06:52:36.132 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
4. 05-31 06:52:36.132 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
5. 05-31 06:52:36.134 32551-32551/exemples.android D/PlaceholderFragment: afterViews 4 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
6. 05-31 06:52:36.134 32551-32551/exemples.android D/PlaceholderFragment: onResume 4 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
• parce que l'adjacence de fragments est décalée d'une position vers la droite, le fragment 4 est réclamé par le conteneur de
fragments ;
• ligne 2 : la méthode [setUserVisibleHint] du fragment 4 est appelée avec [visibleToUser] à false ;
• ligne 3 : la méthode [setUserVisibleHint] du fragment 1 est appelée avec [visibleToUser] à false. En effet, le fragment 1 est
désormais caché ;
• ligne 4 : la méthode [setUserVisibleHint] du fragment 2 est appelée avec [visibleToUser] à true. Le fragment 2 est désormais visible ;
• lignes 5-6 : le cycle de vie du fragment 4 se poursuit ; On passe de l'onglet 2 à l'onglet 3 :
1. 05-31 06:58:16.228 32551-32551/exemples.android D/MainActivity: getItem[4]
2. 05-31 06:58:16.228 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
3. 05-31 06:58:16.228 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
4. 05-31 06:58:16.228 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
5. 05-31 06:58:16.229 32551-32551/exemples.android D/PlaceholderFragment: afterViews 5 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
6. 05-31 06:58:16.229 32551-32551/exemples.android D/PlaceholderFragment: onResume 5 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
• parce que l'adjacence de fragments est décalée d'une position vers la droite, le fragment 5 est réclamé par le conteneur de
fragments ;
• ligne 2 : la méthode [setUserVisibleHint] du fragment 5 est appelée avec [visibleToUser] à false ;
• ligne 3 : la méthode [setUserVisibleHint] du fragment 2 est appelée avec [visibleToUser] à false. En effet, le fragment 2 est
désormais caché ;
• ligne 4 : la méthode [setUserVisibleHint] du fragment 3 est appelée avec [visibleToUser] à true. Le fragment 3 est désormais visible ;
• lignes 5-6 : le cycle de vie du fragment 5 se poursuit ; On passe de l'onglet 3 à l'onglet 4 :
1. 05-31 07:00:17.762 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:00:17.762 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
3. 05-31 07:00:17.762 32551-32551/exemples.android D/PlaceholderFragment: onDestroyView 1 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
• ligne 1 : le fragment 3 est désormais caché ;
• ligne 2 : le fragment 4 est désormais visible. On notera qu'il n'y a pas exécution du cycle de vie du fragment 4. Celui-ci a
déjà été fait deux étapes précédemment ;
• ligne 3 : le fragment 1 sort de l'adjacence du fragment 4 affiché. Sa méthode [onDestroyView] est exécutée. La prochaine
fois qu'il sera affiché, son cycle de vue [onCreateView, afterViews, onResume] sera réexécuté ; On passe de l'onglet 4 à l'onglet 5 :
1. 05-31 07:04:19.004 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:04:19.004 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
3. 05-31 07:04:19.004 32551-32551/exemples.android D/PlaceholderFragment: onDestroyView 2 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
• ligne 1 : le fragment 4 est désormais caché ;
• ligne 2 : le fragment 5 est désormais visible. On notera qu'il n'y a pas exécution du cycle de vie du fragment 5. Celui-ci a
déjà été fait 2 étapes précédemment ;
• ligne 3 : le fragment 2 sort de l'adjacence du fragment 5 affiché. Sa méthode [onDestroyView] est exécutée ;
On passe de l'onglet 5 à l'onglet 1 :
1. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
2. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
3. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
4. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=1, afterViewsDone=false, isVisibleToUser=true, initDone=true, updateDone=false
5. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=2, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
6. 05-31 07:06:17.246 32551-32551/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=2, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
7. 05-31 07:06:17.247 32551-32551/exemples.android D/PlaceholderFragment: update 1 : numVisit=2, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
8. 05-31 07:06:17.247 32551-32551/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
9. 05-31 07:06:17.247 32551-32551/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
10. 05-31 07:06:17.819 32551-32551/exemples.android D/PlaceholderFragment: onDestroyView 4 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
11. 05-31 07:06:17.819 32551-32551/exemples.android D/PlaceholderFragment: onDestroyView 5 : numVisit=1, afterViewsDone=false, isVisibleToUser=false, initDone=true, updateDone=false
• lignes 1, 4, 5, 6 : le cycle de vie du fragment 1 est réexécuté. En effet, il avait perdu la connexion avec sa vue ;
• lignes 2, 5, 8, 9 : pour la même raison le cycle de vie du fragment 2 est réexécuté ;
• lignes 10-11 : les fragments 4 et 5 sortent de l'adjacence du fragment affiché ;
• ligne 7 : le fragment 1 est mis à jour ;
Les logs n'ont jamais montré que les méthodes [setUserVisibleHint] et [onResume] tentaient toutes les deux de mettre à jour le fragment. C'est soit l'une, soit l'autre. Le lecteur est invité à faire d'autres tests et de suivre les logs pour bien comprendre la notion d'adjacence et de cycle de vie des fragments.
1. // nombre de fragments
2. private final int FRAGMENTS_COUNT = 5; 3. // adjacence des fragments
4. private finalint OFF_SCREEN_PAGE_LIMIT = FRAGMENTS_COUNT - 1; Les logs au démarrage sont les suivants :
1. 05-31 07:34:44.717 28908-28908/exemples.android D/MainActivity: constructor 2. 05-31 07:34:44.844 28908-28908/exemples.android D/MainActivity: afterViews 3. 05-31 07:34:44.887 28908-28908/exemples.android D/PlaceholderFragment: constructor 4. 05-31 07:34:44.887 28908-28908/exemples.android D/PlaceholderFragment: constructor 5. 05-31 07:34:44.887 28908-28908/exemples.android D/PlaceholderFragment: constructor 6. 05-31 07:34:44.887 28908-28908/exemples.android D/PlaceholderFragment: constructor 7. 05-31 07:34:44.887 28908-28908/exemples.android D/PlaceholderFragment: constructor 8. 05-31 07:34:45.201 28908-28908/exemples.android D/MainActivity: getItem[0]
9. 05-31 07:34:45.201 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
10. 05-31 07:34:45.201 28908-28908/exemples.android D/MainActivity: getItem[1]
11. 05-31 07:34:45.204 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
12. 05-31 07:34:45.204 28908-28908/exemples.android D/MainActivity: getItem[2]
13. 05-31 07:34:45.204 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
14. 05-31 07:34:45.204 28908-28908/exemples.android D/MainActivity: getItem[3]
15. 05-31 07:34:45.204 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
16. 05-31 07:34:45.205 28908-28908/exemples.android D/MainActivity: getItem[4]
17. 05-31 07:34:45.205 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
18. 05-31 07:34:45.205 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=true, initDone=false, updateDone=false
19. 05-31 07:34:45.207 28908-28908/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
20. 05-31 07:34:45.208 28908-28908/exemples.android D/PlaceholderFragment: afterViews 3 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
21. 05-31 07:34:45.208 28908-28908/exemples.android D/PlaceholderFragment: afterViews 4 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
22. 05-31 07:34:45.209 28908-28908/exemples.android D/PlaceholderFragment: afterViews 5 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
23. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=false, updateDone=false
24. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
25. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
26. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: onResume 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
27. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: onResume 4 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
28. 05-31 07:34:45.210 28908-28908/exemples.android D/PlaceholderFragment: onResume 5 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
29. 05-31 07:34:46.548 28908-28908/exemples.android D/menu: création menu en cours
• les logs montrent que le cycle de vie des 5 fragment est exécuté ;
• le fragment 1 est affiché ligne 18 ;
On passe de l'onglet 1 à l'onglet 2 :
1. 05-31 07:38:27.780 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:38:27.780 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 1 est caché ;
• ligne 2 : le fragment 2 est affiché ; On passe de l'onglet 2 à l'onglet 3 :
1. 05-31 07:39:33.059 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:39:33.059 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 2 est caché ;
• ligne 2 : le fragment 3 est affiché ; On passe de l'onglet 3 à l'onglet 4 :
1. 05-31 07:40:30.362 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:40:30.362 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 3 est caché ;
On passe de l'onglet 4 à l'onglet 5 :
1. 05-31 07:41:23.479 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:41:23.479 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=0, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 4 est caché ;
• ligne 2 : le fragment 5 est affiché ; On passe de l'onglet 5 à l'onglet 1 :
1. 05-31 07:42:22.549 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=1, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:42:22.549 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
3. 05-31 07:42:22.549 28908-28908/exemples.android D/PlaceholderFragment: update 1 : numVisit=2, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 5 est caché ;
• ligne 2 : le fragment 1 est affiché ; • ligne 3 : le fragment 1 est mis à jour ; On passe de l'onglet 1 à l'onglet 4 :
1. 05-31 07:44:13.129 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=2, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=true
2. 05-31 07:44:13.129 28908-28908/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
3. 05-31 07:44:13.129 28908-28908/exemples.android D/PlaceholderFragment: update 4 : numVisit=2, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
• ligne 1 : le fragment 1 est caché ;
• ligne 2 : le fragment 4 est affiché ; • ligne 3 : le fragment 4 est mis à jour ;
On remarque, qu'avec l'adjacence totale, le comportement des fragments est beaucoup plus prévisible.
Maintenant, mettons une adjacence nulle et voyons ce qui se passe. La classe [MainActivity] évolue comme suit : 1. // nombre de fragments
2. private final int FRAGMENTS_COUNT = 5; 3. // adjacence des fragments
4. private finalint OFF_SCREEN_PAGE_LIMIT = 0; Les logs au démarrage sont les suivants :
1. 06-01 03:11:52.068 5679-5679/exemples.android D/MainActivity: constructor 2. 06-01 03:11:52.353 5679-5679/exemples.android D/MainActivity: afterViews 3. 06-01 03:11:52.433 5679-5679/exemples.android D/PlaceholderFragment: constructor 4. 06-01 03:11:52.433 5679-5679/exemples.android D/PlaceholderFragment: constructor 5. 06-01 03:11:52.434 5679-5679/exemples.android D/PlaceholderFragment: constructor 6. 06-01 03:11:52.434 5679-5679/exemples.android D/PlaceholderFragment: constructor 7. 06-01 03:11:52.434 5679-5679/exemples.android D/PlaceholderFragment: constructor 8. 06-01 03:11:52.566 5679-5679/exemples.android D/MainActivity: getItem[0]
9. 06-01 03:11:52.566 5679-5679/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
10. 06-01 03:11:52.566 5679-5679/exemples.android D/MainActivity: getItem[1]
11. 06-01 03:11:52.566 5679-5679/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false
12. 06-01 03:11:52.566 5679-5679/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=true, initDone=false, updateDone=false
13. 06-01 03:11:52.571 5679-5679/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false
14. 06-01 03:11:52.574 5679-5679/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=false, updateDone=false
15. 06-01 03:11:52.574 5679-5679/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false
16. 06-01 03:11:52.574 5679-5679/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false
17. 06-01 03:11:54.597 5679-5679/exemples.android D/menu: création menu en cours
• lignes 8 et 10, on voit que le conteneur de fragments a réclamé 2 fragments, les n°s 1 et 2. Tout se passe donc comme s'il y