• Aucun résultat trouvé

1.9.2 Réécriture du fragment [PlaceholderFragment]

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