• Aucun résultat trouvé

Dans l'architecture précédente, nous avons une activité et n fragments. L'utilisateur interagit avec les différents fragments. Ces interactions modifient l'état de l'application. On appelle ici état de l'application, l'ensemble des informations qu'elle mémorise tout au long de sa vie. Le problème suivant se pose alors :

• lorsque l'utilisateur interagit avec le fragment i, l'application passe d'un état E1 à un état E2 ; • une action de l'utilisateur sur le fragment i fait afficher le fragment j ;

• comment mettre à jour le fragment j avec l'état actuel E2 de l'application ;

Des exemples précédents, nous savons comment mettre à jour le fragment j. Mais où trouver l'état E2 de l'application pour le mettre à jour ?

Il y a différentes solutions à ce problème. Nous en avons vu une : le fragment i peut transmettre l'état E2 de l'application au fragment j via des arguments. Nous avons rencontré cette méthode dans la classe [MainActivity] lors de la création des fragments :

1. for (int i = 0; i < fragments.length; i++) { 2. // on crée un fragment

3. fragments[i] = new PlaceholderFragment_(); 4. // on peut passer des arguments au fragment

5. Bundle args = new Bundle();

6. args.putInt(ARG_SECTION_NUMBER, i + 1); 7. fragments[i].setArguments(args); 8. }

Cette solution n'est pas immédiatement utilisable ici. En effet, lorsque l'utilisateur clique sur l'onglet j qui va faire apparaître le fragment j, notre code n'est pas appelé. C'est uniquement du code système qui s'exécute. Nous verrons dans un prochain projet comment intercepter le clic sur un onglet, mais pour l'instant nous allons adopter une autre voie.

Nous avons parlé d'état de l'application : l'ensemble des données gérées par l'application au fil du temps. Ici l'application est constituée d'une activité et de n fragments tous instanciés une unique fois au démarrage de l'application et dont la durée de vie est celle de l'application. Donc chacun de ces éléments ou plusieurs ensemble peuvent être candidats pour stocker l'état de l'application. Chaque fragment a accès par la méthode [Fragment.getActivity()], à l'activité qui l'a créé . Tous les fragments ayant accès à l'activité, il semble naturel de stocker l'état de l'application dans celle-ci.

Cependant le résultat de la méthode [Fragment.getActivity()] dépend du moment où elle est appelée dans le cycle de vie. Nous illustrons ce point en ajoutant quelques logs dans la classe [PlaceholderFragment] :

1. // update fragment

2. public void update() {

3. Log.d("PlaceholderFragment", String.format("update %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos())); 4. // le travail à faire dépend du n° de la visite

5. if (numVisit > 1) { 6. // log

7. Log.d("PlaceholderFragment", String.format("update %s : %s", getArguments().getInt(ARG_SECTION_NUMBER), getInfos()));

8. // texte modifié

9. textViewInfo.setText(String.format("%s update(%s)", text, (numVisit - 1))); 10. }

11. } 12.

13. // infos locales pour logs

14. private String getInfos() {

15. return String.format("numVisit=%s, afterViewsDone=%s, isVisibleToUser=%s, initDone=%s, updateDone=%s,

getActivity()==null:%s",

16. numVisit, afterViewsDone, isVisibleToUser, initDone, updateDone, getActivity() == null); 17. }

• lignes 14-16 : la méthode [getInfos] affiche partie de l'état de l'application ;

Nous lançons l'application avec une adjacence de fragments de 2. Les logs au démarrage de l'application : 1. 06-01 03:26:13.769 10931-10931/exemples.android D/MainActivity: constructor

2. 06-01 03:26:13.856 10931-10931/exemples.android D/MainActivity: afterViews 3. 06-01 03:26:13.864 10931-10931/exemples.android D/PlaceholderFragment: constructor 4. 06-01 03:26:13.864 10931-10931/exemples.android D/PlaceholderFragment: constructor 5. 06-01 03:26:13.864 10931-10931/exemples.android D/PlaceholderFragment: constructor 6. 06-01 03:26:13.864 10931-10931/exemples.android D/PlaceholderFragment: constructor 7. 06-01 03:26:13.864 10931-10931/exemples.android D/PlaceholderFragment: constructor 8. 06-01 03:26:14.535 10931-10931/exemples.android D/MainActivity: getItem[0]

9. 06-01 03:26:14.538 10931-10931/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 10. 06-01 03:26:14.538 10931-10931/exemples.android D/MainActivity: getItem[1]

11. 06-01 03:26:14.538 10931-10931/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 12. 06-01 03:26:14.538 10931-10931/exemples.android D/MainActivity: getItem[2]

13. 06-01 03:26:14.538 10931-10931/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 14. 06-01 03:26:14.538 10931-10931/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0,

15. 06-01 03:26:14.541 10931-10931/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

16. 06-01 03:26:14.545 10931-10931/exemples.android D/PlaceholderFragment: afterViews 3 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

17. 06-01 03:26:14.547 10931-10931/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=false, updateDone=false, getActivity()==null:false

18. 06-01 03:26:14.547 10931-10931/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false, getActivity()==null:false

19. 06-01 03:26:14.547 10931-10931/exemples.android D/PlaceholderFragment: update 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false, getActivity()==null:false

20. 06-01 03:26:14.547 10931-10931/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

21. 06-01 03:26:14.547 10931-10931/exemples.android D/PlaceholderFragment: onResume 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

22. 06-01 03:26:15.967 10931-10931/exemples.android D/menu: création menu en cours

• lignes 9, 10, 13, 14 : on voit que dans les méthodes [setUserVisibleHint], on a [getActivity()==null] si le fragment n'est pas

encore visible (isVisibleToUser==false) ;

• ligne 19 : on voit que lorsque le flux d'exécution arrive à la méthode [update] du fragment 1, la méthode [getActivity] rend

bien l'activité ;

Lorsqu'on met l'adjacence de fragments à 4 (adjacence totale), les logs sont les suivants : 1. 06-01 03:35:23.553 2814-2814/exemples.android D/MainActivity: constructor

2. 06-01 03:35:23.751 2814-2819/exemples.android I/art: Ignoring second debugger -- accepting and dropping 3. 06-01 03:35:23.900 2814-2814/exemples.android D/MainActivity: afterViews

4. 06-01 03:35:23.991 2814-2814/exemples.android D/PlaceholderFragment: constructor 5. 06-01 03:35:23.991 2814-2814/exemples.android D/PlaceholderFragment: constructor 6. 06-01 03:35:23.991 2814-2814/exemples.android D/PlaceholderFragment: constructor 7. 06-01 03:35:23.991 2814-2814/exemples.android D/PlaceholderFragment: constructor 8. 06-01 03:35:24.002 2814-2814/exemples.android D/PlaceholderFragment: constructor 9. 06-01 03:35:24.207 2814-2814/exemples.android D/MainActivity: getItem[0]

10. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 11. 06-01 03:35:24.207 2814-2814/exemples.android D/MainActivity: getItem[1]

12. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 2 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 13. 06-01 03:35:24.207 2814-2814/exemples.android D/MainActivity: getItem[2]

14. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 3 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 15. 06-01 03:35:24.207 2814-2814/exemples.android D/MainActivity: getItem[3]

16. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 4 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 17. 06-01 03:35:24.207 2814-2814/exemples.android D/MainActivity: getItem[4]

18. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 5 : numVisit=0, afterViewsDone=false, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:true 19. 06-01 03:35:24.207 2814-2814/exemples.android D/PlaceholderFragment: setUserVisibleHint 1 : numVisit=0,

afterViewsDone=false, isVisibleToUser=true, initDone=false, updateDone=false, getActivity()==null:false

20. 06-01 03:35:24.210 2814-2814/exemples.android D/PlaceholderFragment: afterViews 2 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

21. 06-01 03:35:24.211 2814-2814/exemples.android D/PlaceholderFragment: afterViews 3 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

22. 06-01 03:35:24.214 2814-2814/exemples.android D/PlaceholderFragment: afterViews 4 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

23. 06-01 03:35:24.215 2814-2814/exemples.android D/PlaceholderFragment: afterViews 5 numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=false, updateDone=false, getActivity()==null:false

24. 06-01 03:35:24.215 2814-2814/exemples.android D/PlaceholderFragment: afterViews 1 numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=false, updateDone=false, getActivity()==null:false

25. 06-01 03:35:24.215 2814-2814/exemples.android D/PlaceholderFragment: onResume 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false, getActivity()==null:false

26. 06-01 03:35:24.215 2814-2814/exemples.android D/PlaceholderFragment: update 1 : numVisit=1, afterViewsDone=true, isVisibleToUser=true, initDone=true, updateDone=false, getActivity()==null:false

27. 06-01 03:35:24.216 2814-2814/exemples.android D/PlaceholderFragment: onResume 2 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

28. 06-01 03:35:24.216 2814-2814/exemples.android D/PlaceholderFragment: onResume 3 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

29. 06-01 03:35:24.216 2814-2814/exemples.android D/PlaceholderFragment: onResume 4 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

30. 06-01 03:35:24.216 2814-2814/exemples.android D/PlaceholderFragment: onResume 5 : numVisit=0, afterViewsDone=true, isVisibleToUser=false, initDone=true, updateDone=false, getActivity()==null:false

31. 06-01 03:35:26.602 2814-2814/exemples.android D/menu: création menu en cours

On a les mêmes résultats. On en déduit que dès que le fragment est visible la méthode [getActivity] rend l'activité du fragment. On remarque également que lorsque l'exécution atteint la méthode [update] du fragment qui va s'afficher, la méthode [getActivity] rend bien une valeur.