You are on page 1of 43

Tutoriel Android : tout

comprendre sur les Fragments

Android2ee

Par Mathias Seguy

Date de publication : 1 fvrier 2014

Dernire mise jour : 14 janvier 2016

Cet article se propose de vous expliquer ce que sont les fragments et comment mettre les
en place au sein de vos applications.

Pour ragir ce tutoriel, un espace de dialogue vous est propos sur le forum : Commentez
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

I - Dfinition, objectifs et philosophie des Fragments................................................................................................. 4


I-A - Philosophie..................................................................................................................................................... 4
I-B - Dfinition.........................................................................................................................................................4
I-C - Objectifs......................................................................................................................................................... 5
II - Fragments et cycles de vie................................................................................................................................... 7
III - Fragments statiques............................................................................................................................................11
III-A - Mise en place.............................................................................................................................................11
III-A-1 - Cration du fragment.........................................................................................................................11
III-A-2 - Cration de l'activit qui va accueillir le Fragment............................................................................12
III-A-3 - Positionner les fragments..................................................................................................................13
III-B - Structurer une application possdant des fragments................................................................................ 13
III-B-1 - Design Pattern...................................................................................................................................14
III-B-2 - La mthode onItemSelected de l'activit A.......................................................................................14
III-B-3 - Structure du projet.............................................................................................................................15
III-B-4 - Sauvegarder et restaurer le contexte utilisateur............................................................................... 15
III-B-4-a - Mise en place de la restauration avec les fragments............................................................... 16
III-B-5 - Fragment sans I.H.M. : les working fragments................................................................................. 17
III-B-5-a - setRetainInstance......................................................................................................................17
III-B-5-b - Exemple.................................................................................................................................... 17
III-B-6 - Design Pattern de communication fragment-activit.........................................................................18
III-B-7 - Gestion des menus........................................................................................................................... 19
III-B-8 - Nombre de fragments affichs et structuration des layouts.............................................................. 20
IV - Exercice : Migration d'une application existante................................................................................................ 22
V - Multiversionning avec les fragments................................................................................................................... 25
V-A - Fragments natifs et Fragments de la support-library : Le parallel activity pattern...................................... 25
V-A-1 - Utilisation de finish............................................................................................................................. 27
V-B - Mise en place des Fragments de la support-library...................................................................................27
V-B-1 - Migration de l'activit......................................................................................................................... 27
V-B-2 - Migration des fragments.................................................................................................................... 28
V-C - Migration des fichiers de layout................................................................................................................. 28
V-D - Duplication du code....................................................................................................................................29
V-E - Conclusion concernant le multi-versionning : Use only the support-library................................................ 30
VI - Fragment dynamique.......................................................................................................................................... 30
VI-A - Mise en place............................................................................................................................................ 31
VI-B - Gestion des Fragments : FragmentManager et FragmentTransition.........................................................32
VI-C - Initialisation................................................................................................................................................ 33
VI-C-1 - Passage de paramtres lors de la cration du fragment................................................................. 33
VI-C-2 - Bonne pratique du cas particulier de la rotation de l'appareil...........................................................33
VI-D - Structurer une application possdant des fragments................................................................................34
VI-D-1 - Design Pattern.................................................................................................................................. 35
VI-D-2 - La mthode onItemSelected de l'activit A...................................................................................... 36
VI-D-3 - La classe FragmentsSwitcher...........................................................................................................37
VI-D-4 - Fragments et BackStack...................................................................................................................37
VI-D-4-a - Backstack : ne la supposez pas.............................................................................................. 38
VI-D-5 - Nombre de fragments affichs et structuration des layouts............................................................. 38
VI-E - Navigation.................................................................................................................................................. 38
VI-F - Animations..................................................................................................................................................39
VI-F-1 - Mise en place des animations.......................................................................................................... 40
VI-G - Bonnes pratiques...................................................................................................................................... 41
VI-G-1 - Toujours interroger la backstack avant d'instancier un fragment avec findByTag.............................41
VI-G-2 - Autres bonnes pratiques...................................................................................................................41
VI-G-2-a - Le fragment est li au layout qui le contient............................................................................41
VI-G-2-b - Ne jamais r-instancier un fragment avec une rfrence obsolte..........................................42
VI-G-2-c - Toujours utiliser les tags des fragments pour les identifier et les retrouver..............................42
VII - Autres fragments............................................................................................................................................... 42
VII-A - DialogFragment.........................................................................................................................................42
VII-B - PreferenceFragment................................................................................................................................. 42
VIII - Conclusion........................................................................................................................................................ 43

-2-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

IX - Remerciements................................................................................................................................................... 43

-3-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

I - Dfinition, objectifs et philosophie des Fragments

I-A - Philosophie

La philosophie dcoule d'un problme simple qui est l'adaptation d'une application Android toutes les tailles
d'appareils existants.

Tout d'abord, il faut bien comprendre que sans les fragments il tait dj possible de s'adapter toutes les tailles
d'crans. Il suffisait de mettre un layout particulier dans layout-small, layout-normal, layout-large, layout-xlarge, pour
obtenir l'I.H.M. souhaite en fonction des caractristiques de l'cran. Par contre, l'activit qui contrlait tous ces
cas devenait trs complexe ; son nombre cyclothymique explosait, la capacit d'un esprit humain comprendre,
modifier, corriger ou faire voluer l'activit devenait rduite, les mthodes du cycle de vie faisaient 50 100 lignes.
Et finalement, l'activit devenait ingrable.

C'est ce qui a motiv crer les fragments ; les fragments permettent de scinder vos activits en composants
encapsuls et rutilisables qui possdent leur propre cycle de vie et leur propre interface graphique. Cela permet
de mettre en place des I.H.M volues qui s'adaptent aux diffrents crans et leur orientation tout en maintenant
le code de l'activit human readable .

Ainsi, dans l'exemple ci-dessous (celui de Google), nous voyons comment l'activit A s'adapte en fonction de la taille
de l'cran.

Nous voyons aussi qu'il faut une seconde activit qui sera utilise uniquement pour les smartphones. Ainsi, l'utilisation
des fragments change une activit complexe en une application complexe d'activits simplifies. Ce qui est un objectif
fondamental d'architecture.

I-B - Dfinition

Les fragments permettent de scinder vos activits en composants encapsuls et rutilisables qui possdent leur
propre cycle de vie et leur propre interface graphique. Cela permet de mettre en place des I.H.M. volues qui
s'adaptent aux diffrents crans et leur orientation.

Quelques notions lmentaires concernant les fragments :

Ils dportent une partie du traitement de l'activit en leur sein ;


Ils sont lis une activit (ils n'existent pas sans elle) ;

-4-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Ils dfinissent la plupart du temps une interface graphique, mais peuvent aussi tre utiliss
pour retenir un tat lors de la destruction/reconstruction de leur activit parente (le bon vieux
onRetainNonConfigurationInstance) ;
Ils peuvent tre statiques (dfinis une fois pour toutes dans le fichier de layout) ou dynamiques (crs,
supprims, ajouts dynamiquement) ;
Ils sont apparus partir de HoneyComb (level 11) ainsi, pour les mettre en place avant HoneyComb, il faut
utiliser la support-librairy ;
Pour les utiliser, il faut un BuildSDK et un TragetSDK suprieur 11 (cela tombe bien, vous devriez tre 19
l'heure o j'cris ces lignes).

Les classes fondamentales pour la gestion des fragments sont : Fragment, FragmentManager et
FragmentTransaction.

I-C - Objectifs

Vos objectifs sont simples ; il vous faut utiliser les fragments pour vous adapter le plus facilement possible aux
configurations des crans. Ce qui veut dire que je vous parle de Design.

Ainsi vous allez commencer par dfinir vos I.H.M. pour les tablettes 10 pouces, puis pour les 7 pouces et finir par celles
du smartphone. Il faut rutiliser les fragments que vous avez dfinis pour les 10'' et peut-tre dfinir une navigation
pour chaque taille d'cran.

-5-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Nexus 4

-6-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Votre objectif est de construire une application s'adaptant ces tailles d'cran. Remarquez que ce ne sont que des
jalons, il faut aussi que votre application se redimensionne entre ces jalons ; donc toujours pas de tailles en dur.

II - Fragments et cycles de vie

Avant de commencer expliquer l'utilisation des fragments, il faut comprendre quel est le cycle de vie d'un fragment,
comment il se lie celui de l'activit qui le contient.

Comme pour les activits, en fonction du cycle de vie du fragment, il faut savoir sauver, restaurer, instancier, dtruire
les donnes lors des diffrentes tapes de ce cycle.

Pour rappel, quand on est dans une activit :

Dans onCreate, on instancie les objets ;


Dans onStart, on lance les traitements ;
Dans onResume, on s'abonne et on remet le contexte utilisateur ;
Dans onPause, on se dsabonne et on enregistre le contexte utilisateur ;
Dans onStop on arrte les traitements et on dsalloue les objets ;
Dans onDestroy on ne fait rien (elle n'est pas appele systmatiquement), on prfre utiliser les mthodes de
type onTrimMemory pour connatre l'tat de l'application dans le LRU cache.

Ces principes s'appliquent aux fragments de la mme manire. Ainsi quand on est dans un fragment :

Dans onAttach, on rcupre un pointeur vers l'activit contenante (attention aux NullPointerException, celle-ci
n'a pas finalis sa construction) ;
Dans onCreate, on instancie les objets non graphiques ;
Dans onCreateView, on instancie la vue et les composants graphiques ;
Dans onActivityCreate, on rcupre un pointeur sur l'activit (qui est construite), on lance les initialisations qui
ont besoin de cette activit, on restaure le contexte des fragments et utilisateur.
Dans onStart, on lance les traitements ;
Dans onResume, on s'abonne et on remet le contexte utilisateur ;
Dans onPause, on se dsabonne et on enregistre le contexte utilisateur ;
Dans onStop, on arrte les traitements et on dsalloue les objets ;
Dans onDestroyView, la vue est dtache de celle de l'activit, on peut dlivrer la mmoire des objets
graphiques ;
Dans onDestroy, je ne prconise pas grand-chose ;
Dans onDetach, non plus.

Personnellement, je surcharge systmatiquement les mthodes suivantes :

Dans le cadre d'une activit onCreate, onResume, onPause, onSaveInstance, onRestoreInstance et onStop ;
Dans le cadre d'un fragment onCreate, onCreateView, onActivityCreated, onResume, onPause,
onSaveInstance et onStop.

L'intrication du cycle de vie d'une activit et d'un fragment se lit dans les logs suivants :

1. 12-11 16:41:19.188: E/MainActivityHC(9879): onCreate called


2. 12-11 16:41:19.258: W/MainFragmentHC(9879): onAttach called
3. 12-11 16:41:19.258: W/MainFragmentHC(9879): onCreate called
4. 12-11 16:41:19.268: W/MainFragmentHC(9879): onCreateView called
5. 12-11 16:41:19.318: E/MainActivityHC(9879): onCreate finished
6. 12-11 16:41:19.318: W/MainFragmentHC(9879): onActivityCreated called
7. 12-11 16:41:19.318: E/MainActivityHC(9879): onStart called
8. 12-11 16:41:19.318: E/MainActivityHC(9879): onStart finished
9. 12-11 16:41:19.318: W/MainFragmentHC(9879): onStart called
10. 12-11 16:41:19.318: E/MainActivityHC(9879): onResume called
11. 12-11 16:41:19.318: E/MainActivityHC(9879): onResume finished
12. 12-11 16:41:19.318: W/MainFragmentHC(9879): onResume called

-7-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

13. 12-11 16:41:35.528: W/MainFragmentHC(9879): onPause called


14. 12-11 16:41:35.528: E/MainActivityHC(9879): onPause called
15. 12-11 16:41:35.528: E/MainActivityHC(9879): onPause finished
16. 12-11 16:41:36.088: W/MainFragmentHC(9879): onStop called
17. 12-11 16:41:36.108: E/MainActivityHC(9879): onStop called
18. 12-11 16:41:36.108: E/MainActivityHC(9879): onStop finished
19. 12-11 16:41:36.128: W/MainFragmentHC(9879): onDestroyView called
20. 12-11 16:41:36.168: W/MainFragmentHC(9879): onDestroy called
21. 12-11 16:41:36.168: W/MainFragmentHC(9879): onDetach called
22. 12-11 16:41:36.178: E/MainActivityHC(9879): onDestroy called
23. 12-11 16:41:36.178: E/MainActivityHC(9879): onDestroy finished

Ce qui se visualise avec le schma suivant :

-8-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Les fragments possdent leur propre cycle de vie et celui-ci est intimement li celui de l'activit qui le contient.

Fondamental :

-9-
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Toute mthode surcharge de ce cycle de vie doit imprativement appeler son super, sinon une
exception sera leve au RunTime (exception faite de onCreateView).

onCreateView

Dans la pratique, la mthode onCreateView est la mthode que l'on utilise pour crer la vue qui sera affiche par le
fragment. C'est la mthode qui est systmatiquement surcharge.

public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) possde les
arguments suivants :

inflater : Il permet de gonfler le fichier xml de layout ;


container : Si non-null, correspond la vue parente qui contient le fragment et laquelle la vue du fragment
va s'attacher ;
savedInstanceState : si non-null, le fragment est reconstruit partir d'un tat prcdent sauvegard et
transmis par ce paramtre.

Le code typique de la mthode onCreateView gonfle le fichier xml pour en construire une vue et la renvoyer :

1. @Override
2. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
3. View view = inflater.inflate(R.layout.speaker_detail, container, false);
4. return view;
5. }

Autres mthodes

Comme pour les activits, les bonnes pratiques sont :

onCreate permet de crer les objets de la classe pour qu'ils soient instancis une seule fois dans le cycle de
vie du fragment ;
onCreate ne cre pas l'interface graphique ;
onCreateView cre l'interface graphique ;
onActivityCreated permet de rcuprer un pointeur vers l'activit ;
onDestroy n'est pas toujours appele (que ce soit pour l'activit comme pour le fragment) ;
onAttach permet de rcuprer une instance de l'activit parente, mais attention, elle n'a pas fini son
initialisation (il vaut mieux attendre onActivityCreated).

Un fragment peut finir son cycle de vie sans que l'activit ne modifie le sien (reste l'tat actif).

- 10 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

III - Fragments statiques

III-A - Mise en place

Nous allons voir dans ce chapitre comment mettre en place une activit qui contient un fragment de manire statique.

Un fragment statique ne peut tre ni supprim, ni remplac ; il est statique.

III-A-1 - Cration du fragment

L'interface graphique du fragment se dfinit dans un fichier xml. Il n'y a aucune diffrence entre un fichier xml de
layout (avant HoneyComb) pour une activit et un fichier xml de layout pour un fragment. Vous pouvez utiliser les
mmes composants graphiques, les mmes layouts, la syntaxe est identique. Il n'y a pas de diffrence.

1. <LinearLayout
2. android:layout_width="wrap_content"
3. android:layout_height=" fill_parent">
4.
5. <TextView
6. android:id="@+id/name"
7. android:layout_width="fill_parent"
8. android:layout_height="wrap_content"
9. android:text="@string/hello" />
10.
11. <ListView
12. android:id="@+id/myListView"
13. android:layout_width="fill_parent"

- 11 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

14. android:layout_height="wrap_content"/>
15.
16. </LinearLayout>

Votre classe Fragment (MyFragment par exemple) tend simplement Fragment et la seule chose obligatoire est de
surcharger la mthode onCreateView.

1. @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle


savedInstanceState) {
2. View view = inflater.inflate(R.layout.speaker_detail, container, false);
3. //Instancier vos composants graphique ici (fates vos findViewById)
4. return view; }

Le point important se produit lors du gonflage de la vue inflater.inflate(R.layout.speaker_detail, container, false). En


effet, le dernier paramtre est false . Ce paramtre spcifie si la vue doit tre automatiquement attache son
container parent. Dans le cas d'un fragment, cette liaison doit tre laisse au systme qui se charge de la rattacher
comme il se doit l'activit.

C'est dans cette classe que vous allez coder votre comportement, faire vos findViewById et tout le code que vous
auriez mis dans votre activit. Il suffit de coder comme avant , directement dans votre fragment.

III-A-2 - Cration de l'activit qui va accueillir le Fragment

Pour qu'une activit utilise un fragment statique, il suffit de dclarer le fragment en tant qu'objet graphique au sein
du fichier de layout de votre activit.

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android" android:layout_width="fill_parent"android:layout_height="fill_parent"
3. android:orientation="vertical" >
4.
5. <fragment
6. android:id="@+id/list"
7. android:layout_width="fill_parent"
8. android:layout_height="fill_parent"
9. android:name="com.android2ee.tuto.fragment.sample1.ListFragment"
10. android:orientation="horizontal" >
11. </fragment>
12.
13. </LinearLayout>

Les points importants sont :

La balise fragment (en minuscule je vous prie) ;


la balise android:name qui permet de spcifier quelle est la classe qui prend en charge l'implmentation du
fragment ;
La balise android:id (resp. android:tag qui permet de spcifier un identifiant entier (resp. de type String)
unique au fragment, ce qui est trs important lors de la manipulation dynamique des fragments ;
Et bien sr, la manire dont le fragment remplit l'espace via les balises layout_width et layout_height.

Et voil, c'est termin, la mthode onCreate de votre activit ressemble a :

1. @Override
2. public void onCreate(Bundle savedInstanceState) {
3. super.onCreate(savedInstanceState);
4. //Dfinissez votre vue, rien de plus. Tout sera pris en charge par le fragment qui affiche les donnes
5. setContentView(R.layout.activity_main);
6. //Retrouver votre fragment en utilisant son identifiant (si besoin)
7. MainFragmentHC mainFragment=(MainFragmentHC)findViewById(R.id.list_fragment);
8. }

- 12 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Vous pouvez lancer votre application, elle s'excutera.

III-A-3 - Positionner les fragments

Le plus efficace pour positionner les fragments est d'utiliser la balise weight qui permet de rpartir l'espace libre entre
les composants graphiques affichs au sein d'un LinearLayout. Cela va vous permettre de les positionner o vous le
souhaitez dans l'espace tout en leur donnant leur proportion les uns par rapport aux autres.

Ainsi, vous souhaitez que le fragment A prenne 1/3 de l'espace en largeur et le fragment B 2/3, il vous suffit de les
dclarer de la manire suivante :

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="horizontal"
4. android:layout_width="match_parent"
5. android:layout_height="match_parent">
6.
7. <fragment android:name="com.example.news.FragmentA"
8. android:id="@+id/list"
9. android:layout_weight="1"
10. android:layout_width="0dp"
11. android:layout_height="match_parent" />
12.
13. <fragment android:name="com.example.news.FragmentB"
14. android:id="@+id/viewer"
15. android:layout_weight="2"
16. android:layout_width="0dp"
17. android:layout_height="match_parent" />
18.
19. </LinearLayout>

L'astuce, ici, est de demander une taille de 0dp aux fragments. L'espace libre restant correspond la largeur complte
du layout. La balise weight redistribue cet espace libre chacun des composants 1/3 pour le fragment A qui pse 1
(car 1+2=3 et vaut le poids total) et 2/3 pour le fragment B qui pse 2.

III-B - Structurer une application possdant des fragments

Revenons concrtement l'exemple de Google sur les fragments :

Il y a l'activit A qui possde un ou deux fragments en fonction de son contexte d'excution. Le fragment A affiche
une liste, le fragment B affiche l'item de la liste slectionn.

- 13 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Mais alors que fait la mthode onListItemSelected du fragment A, connait-elle fragment B ? Et comment communique-
t-elle avec lui ?

III-B-1 - Design Pattern

En fait le principe est le suivant :

L'activit A connait les fragments qu'elle contient. Les fragments ne connaissent pas leur conteneur, mais uniquement
les CallBack que l'activit A implmente.

L'activit se charge l'orchestration de ses fragments, elle les coute et les met jour. C'est elle de passer
l'information de l'un l'autre, de lancer une activit paire pour afficher le second (cas statique) ou de changer les
fragments (cas dynamique).

III-B-2 - La mthode onItemSelected de l'activit A

Ainsi, dans l'exemple de Google, le fragment A appelle l'activit A (via le onItemSelected de l'interface
FragmentACallBack). L'activit A doit alors connaitre son contexte ; si elle affiche deux fragments, elle doit mettre le
second fragment jour, si elle n'affiche qu'un fragment, elle doit lancer l'activit B.

En code cela donne :

1. //Quelque part dans ActivityA extends Activity


2. // Cas statique
3. public void onItemSelected(String id) {
4. // Si deux panels sont visibles,
5. if (mTwoPane) {
6. ItemDetailFragment fragment = getSupportFragmentManager().getFragmentByTag(itemDetailTag);
7. fragment.setItem(id)
8. } else {
9. // Lancement de l'activit B : Dfinition de l'Intent
10. Intent detailIntent = new Intent(this, ItemDetailActivity.class);
11. // Ajout des paramtres d'initialisation de l'activit

- 14 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

12. detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);


13. // Lancement de l'activit
14. startActivity(detailIntent);
15. }
16. }

III-B-3 - Structure du projet

Le projet ci-contre implique la structure suivante:

src
ActivityA (extends Activity implements FragmentACallBack, FragmentBCallBack)
ActivityB (extends Activity implements FragmentBCallBack)
FragmentA (extends Fragment)
FragmentACallBack
FragmentB (extends Fragment)
FragmentBCallBack
res\layout
activity_a_layout
activity_b_layout
fragment_a_layout
fragment_b_layout
res\layout-port||res\layout-large||res\layout-xlarge
activity_a_layout

III-B-4 - Sauvegarder et restaurer le contexte utilisateur

L'un des lments les plus importants lorsque l'on dveloppe une application Android est de ne pas perdre le
contexte utilisateur quand celui-ci tourne son cran (entre autres). Ainsi quand l'application est dtruite pour tre
immdiatement recre, il nous faut sauvegarder puis restaurer ce contexte ; cela peut tre les valeurs contenues
dans les EditText, les choix des cases cocher, l'item de la liste slectionn, la valeur de la scrollView

Pour mettre en place cette restauration, l'activit utilise les mthodes onRestoreInstanceState et
onSaveInstanceState qui permettent de stocker dans un Bundle (une HashMap type) les diffrents champs primitifs
ou parcelables que l'on souhaite passer de l'activit mourante l'activit recre.

Un exemple de l'utilisation de ces mthodes dans une activit :

1. /*******************************************************************/
2. /** Managing Rotation change ***************************************/
3. /*******************************************************************/
4. /* * (non-Javadoc)
5. * * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle)
6. */
7. @Override
8. protected void onRestoreInstanceState(Bundle savedInstanceState) {
9. super.onRestoreInstanceState(savedInstanceState);
10. // Restauration des donnes du contexte utilisateur
11. edtMessage.setText(savedInstanceState.getString(EDT));
12. for (Parcelable human : savedInstanceState.getParcelableArrayList(LIST)) {
13. messages.add((Human) human);
14. }
15. }
16.
17. /*
18. * (non-Javadoc)
19. *
20. * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
21. */
22. @Override

- 15 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

23. protected void onSaveInstanceState(Bundle outState) {


24. super.onSaveInstanceState(outState);
25. // Sauvegarde des donnes du contexte utilisateur
26. outState.putString(EDT, edtMessage.getText().toString());
27. outState.putParcelableArrayList(LIST, messages);
28. }

Dans cet exemple, nous stockons et restaurons la chane de caractres contenue dans l'EditText edtMessage ainsi
que la liste des objets (ici, des humains) affichs par la listView.

La mthode onSaveInstanceState possde pour paramtre le bundle (outState) qui sera renvoy en paramtre de
la mthode onRestoreInstanceState (savedInstanceState). Ainsi, dans la mthode onSaveInstanceState on stocke
les donnes sauvegarder dans ce bundle et dans la mthode onRestoreInstanceState on les restaure partir de
ce bundle.

Ces mthodes sont appeles dans le cycle de vie de l'activit de la manire suivante :

1. E/MainActivity(10447): MainActivityHC Launched


2. E/MainActivityHC(10447): onCreate called
3. E/MainActivityHC(10447): onStart called
4. E/MainActivityHC(10447): onResume called
5. <-- Rotation de l'cran-->
6. E/MainActivityHC(10447): onPause called
7. E/MainActivityHC(10447): onSaveInstanceState called
8. E/MainActivityHC(10447): onStop called
9. E/MainActivityHC(10447): onDestroy called
10. E/MainActivityHC(10447): onCreate called
11. E/MainActivityHC(10447): onStart called
12. E/MainActivityHC(10447): onRestoreInstanceState called
13. E/MainActivityHC(10447): onResume called

III-B-4-a - Mise en place de la restauration avec les fragments

Pour mettre en place cette technique avec des fragments, il suffit de surcharger la mthode onSaveInstanceState,
comme pour les activits. Par contre, la mthode onRestoreInstanceState n'existe plus dans les fragments, le bundle
est renvoy directement aux mthodes du cycle de vie du fragment. Ainsi, le Bundle outState est disponible en
paramtre des mthodes :

onCreate(Bundle) ;
onCreateView(LayoutInflater, ViewGroup, Bundle) ;
onActivityCreated(Bundle).

Il vous suffit de restaurer vos donnes dans l'une de ces trois mthodes, au moment qui vous semble le plus
appropri :

1. public void onActivityCreated(Bundle savedInstanceState) {


2. super.onActivityCreated(savedInstanceState);
3. if (savedInstanceState != null) {
4. // Restauration des donnes du contexte utilisateur
5. mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
6. }
7. }
8.
9. public void onSaveInstanceState(Bundle outState) {
10. super.onSaveInstanceState(outState);
11. // Sauvegarde des donnes du contexte utilisateur
12. outState.putInt("curChoice", mCurCheckPosition);
13. }

Faites bien attention vrifier que savedInstanceState est non-null (et donc que vous tes bien dans le pattern
destruction-recration avant de restaurer les donnes).

- 16 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Un dernier petit dtail, mais on y reviendra, n'utilisez pas la mthode setRetainInstance sur ce type de fragment car
alors le bundle SavedInstanceState est toujours null.

III-B-5 - Fragment sans I.H.M. : les working fragments

Tant qu' tre dans la problmatique de la sauvegarde et de la restauration des donnes lors d'un changement de
configuration de l'appareil (cas de la rotation de l'cran), penchons-nous sur le problme de la rtention d'objets qui
ne peuvent tre ni parcelables, ni primitifs, ni serializables.

L'exemple typique est la gestion des Threads (qui, si vous avez une bonne architecture, ne devrait jamais arriver).
Vous souhaitez retenir l'instance de la Thread si votre activit est dtruite pour tre immdiatement reconstruite.
Avant, vous utilisiez la mthode onRetainConfigurationInstance de la classe activit. Cette mthode est dprcie
depuis HoneyComb.

En effet, depuis HoneyComb, il est prconis d'utiliser des fragments sans I.H.M. qui on demande de ne pas mourir
lors du processus de destruction/recration de l'activit qui les contient. Ainsi vous crez un fragment sans I.H.M.
(une vraie classe par exemple, MyWorkingFragment extends Fragment).

Pour qu'un fragment ne soit pas dtruit lorsque l'activit est dtruite pour tre recre, il suffit d'appeler la mthode
setRetainInstance(true) sur ce fragment.

III-B-5-a - setRetainInstance

La mthode setRetainInstance contrle si l'instance du fragment est retenue lors de la recration de l'activit
(comme lors d'un changement de configuration). Elle peut tre utilise uniquement avec des fragments qui
n'appartiennent pas la BackStack (car ils sont persists, quoi qu'il arrive). S'il est dfini true, le cycle de vie du
fragment sera lgrement diffrent quand l'activit sera recre :

OnDestroy() ne sera pas appele (mais onDetach() le sera toujours, parce que le fragment est dtach de
son activit actuelle).
onCreate(Bundle) ne sera pas appele car le fragment n'est pas recr.
onAttach(Activity) et onActivityCreated(Bundle) seront encore appeles. (JavaDoc).

Cette mthode ne doit pas tre appele sur les fragments normaux, sinon dites adieu votre BackStack de
fragments.

III-B-5-b - Exemple

La mise en place de ce principe est assez simple : quelque part dans votre code, vous appelez sur le dit fragment
(en interne ou pas) setRetainInstance(true) :

1. private static final String WORKER_FRAGMENT_TAG="WORKER_FRAGMENT_TAG";


2.
3. // Quelque part dans votre code
4. workerFragment.setRetainInstance(true);
5.
6. //****************/
7. // Ailleurs dans votre code (dans onCreate, onResume ou onStart)
8. FragmentManager fm = getSupportFragmentManager();
9. FragmentTransaction ft=fm.beginTransaction();
10. ft.add(workerFragment, WORKER_FRAGMENT_TAG);
11. ft.commit();
12. //****************/
13.
14. //Ailleurs dans le code
15. //Pour rcuprer votre working fragment
16. WorkerFragment workerFragment=(workerFragment)fm.findFragmentByTag(WORKER_FRAGMENT_TAG);

- 17 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Il faut ainsi utiliser le tag pour identifier le fragment (en effet n'ayant pas d'I.H.M., il ne possde pas d'identifiant).

III-B-6 - Design Pattern de communication fragment-activit

Un lment bien comprendre dans l'utilisation des fragments. L'objectif d'un fragment est d'tre utilis par plusieurs
activits. De ce fait, le fragment ne peut pas connatre l'activit qui le contient. Mais alors comment communique-
t-il avec elle ? L'ide est simple, toute activit qui souhaite contenir un fragment implmente une interface qui sera
utilise par le fragment pour communiquer avec son conteneur.

Inversement, une activit connait les fragments qu'elle contient, elle peut donc pointer directement sur eux.

Ce principe se rsume ainsi :

Un exemple :

L'interface :

1. public interface MainFragmentCallBack {


2. /**
3. * Un item a t slectionn dans le fragment
4. * En tant que CallBack du fragment, vous devriez faire quelque chose avec cette information
5. * @param itemId
6. */
7. public void onItemSelected(int itemId);
8. }

La classe de l'activit :

1. public class MainActivityHC extends Activity implements MainFragmentCallBack {


2. /*Some code*/

- 18 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

3.
4. /* * (non-Javadoc)
5. *
6. * @see com.android2ee.tuto.fragment.fragmentstatic.tuto.view.honeycomb.main.MainFragmentCallBack#onItemSelect
7. */
8. @Override
9. public void onItemSelected(int itemId) {
10. //Fates votre traitement ici
11. }
12. }

La classe du fragment :

1. public class MainFragmentHC extends Fragment {


2. /**
3. * La parent du fragment (son callback/sonactivit contenante)
4. */
5. private MainFragmentCallBack parent;
6.
7. /*
8. * (non-Javadoc)
9. *
10. * @see android.app.Fragment#onAttach(android.app.Activity)
11. */
12. @Override
13. public void onAttach(Activity activity) {
14. Log.w("MainFragmentHC", "onAttach called");
15. super.onAttach(activity);
16. // Utiliser cette mthode pour lier votre fragment avec son callback
17. parent = (MainFragmentCallBack) activity;
18. }
19.
20. /**
21. * Un item a t slectionn, notifier le changement
22. * @param position of the item
23. */
24. public void onItemSelected(int position) {
25. //Notifiez le parent qu'un item a t slectionn
26. parent.onItemSelected(position);
27. //Fates d'autres traitements ici au besoin
28. }
29. }

Ce pattern est obligatoire ds lors qu'un fragment est contenu par plus d'une activit ; il est recommand dans tous
les cas.

Inversement, vous pouvez, dans vos fragments, appeler la mthode getActivity pour rcuprer le contexte si vous
en avez besoin. Il vous faut alors n'utiliser que les mthodes de la classe activit (pas de mthode spcifique).

III-B-7 - Gestion des menus

Il est naturel que les fragments souhaitent rajouter des MenuItem quand ils sont actifs. En effet, ils doivent porter les
actions associes aux lments qu'ils affichent.

Pour cela, vous devez dans le fragment :

invoquer setHasOptionMenu(true) dans la mthode onCreate du fragment ;


Surcharger les mthodes onCreateOptionsMenu et onOptionsItemSelected, comme pour les activits.

Dans l'activit :

Surcharger les mthodes onCreateOptionsMenu et onOptionsItemSelected, comme d'habitude et rajouter


dans le default un appel au super pour que les menus des fragments soient pris en compte.

- 19 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Ainsi :

Le code de l'activit :

1. public boolean onCreateOptionsMenu(Menu menu) {


2. //Appelez le super pour collecter les menu items de vos fragments
3. super.onCreateOptionsMenu(menu);
4. //Construisez le menu de l'activit
5. getMenuInflater().inflate(R.menu.activity_menu, menu);
6. //et voil
7. return true;
8. }
9. @Override
10. public boolean onOptionsItemSelected(MenuItem item) {
11. switch (item.getItemId()) {
12. case R.id.menu_activity_item1:
13. // Faire un truc, ce menu item appartient l'activit, c'est elle de le traiter
14. return true;
15. default:
16. //Appelez vos fragments pour qu'ils vrifient si ce menu item n'est pas sous leur responsabilit
17. return super.onOptionsItemSelected(item);
18. }}

Le code du fragment :

1. public void onCreate(Bundle savedInstanceState) {


2. super.onCreate(savedInstanceState);
3. setHasOptionsMenu(true);
4. }
5. public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
6. inflater.inflate(R.menu.fragment_menu, menu);
7. super.onCreateOptionsMenu(menu);
8. }
9. public boolean onOptionsItemSelected(MenuItem item) {
10. switch (item.getItemId()) {
11. case R.id.fragment_menu_item1:
12. // Fates un truc, ce menu item appartient au fragment, c'est lui de le traiter
13. return true;
14. default:
15. //Continuez chercher quelqu'un qui va grer ce menu
16. return super.onOptionsItemSelected(item);
17. }}

III-B-8 - Nombre de fragments affichs et structuration des layouts

Vous verrez qu'un lment fondamental dans vos gestions des fragments est de rpondre la question suivante
Combien de fragments suis-je en train d'afficher ? . Certains font des calculs complexes ou demandent aux
fragments de dire l'activit qu'ils sont visibles ou je ne sais quel algorithme tordu.

Restez simple et efficace, utilisez les ressources !

Tout d'abord, vous allez dfinir vos fichiers de layouts dans le dossier res\layout (et pas de suffixe). L vous allez dfinir
vos fichiers main_activity_two_panes.xml, main_activity_one_pane.xml (et d'autres 3, 4 ou plus de fragments,
si vous en avez besoin). Ainsi tous vos fichiers de description des I.H.M. sont au mme endroit.

Maintenant, votre activit va charger le fichier main_activity.xml (qui n'existe pas, on est bien d'accord) :

1. public void onCreate(Bundle savedInstanceState) {


2. super.onCreate(savedInstanceState);
3. //Construisez la vue de l'activit, rien de plus. Le fragment prend en charge le reste.
4. setContentView(R.layout.main_activity);
5. }

- 20 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Et l vous allez utiliser les redirections dans vos ressources :

Pour cela, vous allez crer les dossiers values-large, values-land, values-large-land et dans chacun de ces dossiers
vous allez crer le fichier refs.xml (vous auriez pu l'appeler toto.xml mais refs possde une smantique plus claire).
Ce fichier refs.xml est le suivant :

1. <resources>
2. <item name="main_activity" type="layout">@layout/activity_two_panes</item>
3. <bool name="twoPane">true</bool>
4. </resources>

D'une part il redirige le layout main_activity.xml vers le layout activity_two_pane et d'autre part il spcifie le boolen
twoPane true, car le layout activity_two_panes possde bien deux fragments (two panes signifiant deux panneaux).

Si vous souhaitiez que dans cette configuration, le layout ne possde qu'un seul fragment, il suffisait de rediriger
vers activity_one_pane :

1. <resources>
2. <item name="activity_main" type="layout">@layout/main_activity_one_pane</item>
3. <bool name="twoPane">false</bool>
4. </resources>

Enfin, vous auriez pu remplacer le boolen twoPane par un entier :

1. <resources>
2. <item name="activity_main" type="layout">@layout/main_activity_one_pane</item>
3. <int name="fragmentNumber">3</int>
4. </resources>

Dans votre activit, ou n'importe o dans votre code, pour connaitre ce nombre de fragments, ou le boolen twoPane,
il vous suffit de faire l'appel suivant :

1. //Rcuprez le nombre de fragments affichs


2. boolean twoPane = getResources().getBoolean(R.bool.twoPane);

Vous avez ainsi accompli deux choses :

Pas de duplication inutile des fichiers de layout (factorisation et redirection) ;


Parfaite connaissance du nombre de fragments affichs (contexte des fragments).

Et le projet, votre quipe et l'quipe de maintenance vous en remercie.

Votre projet est structur de la manire suivante :

- 21 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

IV - Exercice : Migration d'une application existante

Je vous propose un exercice cette tape. Cela vous rassurera et vous verrez que, mme si ce que je dis parat
compliqu, cela ne l'est plus quand on l'a fait une fois.

Vous allez prendre l'un de vos projets qui n'a pas de fragment (commencez par un petit projet) et nous allons migrer
l'activit principale ensemble.

0. Ajoutez la support library votre projet.

Clic droit sur le projet Android->AddSupportLibrary

1. Crez le fragment :

public class MyFragment extends android.support.v4.app.Fragment {

- 22 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

2. Crez le fichier myfragment_layout.xml de layout de votre fragment dans res\layout. Copiez/collez le code xml
du layout de votre activit dans ce nouveau fichier.

3. Modifiez le fichier de layout de votre activit pour qu'il affiche le fragment. Vous allez ainsi remplacer le
contenu du fichier par un truc qui ressemble a :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<fragment
android:id="@+id/myfragment"
android:name="yourPackage.MyFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Il faut remplacer yourPackage par le package qui contient votre classe MyFragment.

4. Ouvrez la classe de votre activit et modifiez-la ainsi :

1. public class MainActivity extends FragmentActivity{


2. /**
3. * Le fragment
4. */
5. MyFragment fragment;
6.
7. @Override
8. protected void onCreate(Bundle savedInstanceState) {
9. super.onCreate(savedInstanceState);
10. setContentView(R.layout.activity_main);
11. fragment = (MyFragment)
12. getSupportFragmentManager().findFragmentById(R.id.myfragment);
13.
14. }

Notez que l'identifiant du fragment est celui que vous lui avez donn dans sa dclaration dans le fichier de layout
de l'activit.

Notez aussi que votre activit tend maintenant FragmentActivity.

5. Ouvrez les classes MyFragment et celle de votre activit cte cte (a va aider).

6. Il va falloir maintenant migrer le code de l'activit vers le fragment. La premire tape est la ventilation de la
mthode onCreate de l'activit dans les mthodes onActivityCreate et onCreateView du fragment.

Commencez par coupez/collez tous les champs graphiques (TextView, EditText,) de l'activit dans le fragment.

Dans onCreateView, vous construisez votre vue puis vous instancier vos lments graphiques. Ainsi vous coupez/
collez toutes les lignes contenant un findViewById du onCreate de l'activit vers le onCreateView du fragment. La
mthode onCreateView ressemble a :

1. // Dans MyFragment
2. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
3. View view = inflater.inflate(R.layout.fragment_layout, container, false);
4. //Exemple d'instanciation d'lments graphiques. Ils devraient tre ceux de votre activit.
5. btnAdd = (Button) view.findViewById(R.id.btnAdd);
6. lsvWordsList = (ListView) view.findViewById(R.id.lsvWordsList);
7. edtMessage = (EditText) view.findViewById(R.id.edtMessage);
8. return view;

- 23 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

9. }

Dans la mthode onActivityCreate vous coupez/collez toutes les lignes qui restent dans le onCreate de l'activit. Du
coup, elle ressemble quelque chose comme a :

1. // Dans MyFragment
2. private Context ctx ;
3. public void onActivityCreated(Bundle savedInstanceState) {
4. ctx = getActivity();
5. if (savedInstanceState != null) {
6. edtMessage.setText(savedInstanceState.getString(EdtStorageKey));
7. }
8. //Instanciation des lments de la ListView
9. humans = new ArrayList<Human>();
10. humanAdapter = new HumanAdapter(ctx, humans);
11. lsvWordsList.setAdapter(humanAdapter);
12. // Ajout des listeners
13. btnAdd.setOnClickListener(new OnClickListener() {
14. public void onClick(View v) {
15. add();}
16. });
17. lsvWordsList.setOnItemClickListener(new OnItemClickListener() {
18. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
19. listItemSelected(position);}
20. });
21. super.onActivityCreated(savedInstanceState);
22. }

Si un champ de cette mthode n'appartient pas au fragment, coupez/collez sa dclaration de l'activit dans le
fragment.

La mthode onCreate de l'activit devrait ressembler cela :

1. // Dans l'activit
2. @Override
3. protected void onCreate(Bundle savedInstanceState) {
4. super.onCreate(savedInstanceState);
5. // Construire la vue
6. setContentView(R.layout.activity_main);
7. myFragment=(MyFragment)
8. getSupportFragmentManager().findFragmentById(R.id.myfragment);
9. }

7. Il ne vous reste plus qu' migrer toutes les mthodes de l'activit qui sont associes la gestion de l'I.H.M.
dans le fragment.

Pour les migrer, vous les coupez/collez et vous faites pareil avec les attributs de classe qu'elles utilisaient dans
l'activit.

Votre activit ne doit alors plus contenir que les mthodes qui affichent les fentres de dialogue, gre le cycle de vie,
les menus. Votre fragment doit grer tous les vnements de l'I.H.M.

Si, dans votre fragment, le code ne marche pas, c'est souvent qu'il lui manque le contexte. Ne vous inquitez pas,
vous avez le contexte. Vous l'avez instanci dans la mthode onActivityCreated, il vous suffit de rajouter ctx devant
les mthodes qui ne marchent pas.

Par exemple vous avez coup/coll :

humanAdapter = new HumanAdapter(this, humans);

Remplacez this par ctx :

- 24 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

humanAdapter = new HumanAdapter(ctx, humans);

Et votre code compile de nouveau.

Si vous avez besoin d'appeler une mthode de l'activit partir du fragment, cela signifie que vous devez crer la
classe MyFragmentCallBack et y dfinir cette mthode. Puis, vous allez implmenter l'interface MyFragmentCallBack
par l'activit et vous pourrez ainsi appeler cette mthode via myFragmentCallBack.maMethode(). Dans ce cas,
n'oubliez pas de rajouter le callBack votre fragment :

1. // Dans MyFragment
2. public void onAttach(Activity activity) {
3. super.onAttach(activity);
4. myCallBack=(MyFragmentCallBack)activity;
5. }

Normalement, vous tes capable de terminer la migration en corrigeant les erreurs de compilation assez facilement.

8. A ce stade vous avez fini. Votre activit est quasiment vide et votre fragment gre l'interface graphique.

V - Multiversionning avec les fragments

Dans la confrence 106 - Multiversionning Android User Interfaces - I_O 2012 de Bruno Oliveira et Adam Powell
des Google I/O 2012, ils nous ont expliqu comment grer le multiversionning avec les fragments. C'est--dire
comment mettre en place les fragments quelle que soit la version du systme.

Je vais aussi vous l'expliquer. Mais surtout, je vais vous expliquer pourquoi il ne faut pas mettre en place leur solution.

Sachez que si vous utilisez la support-library pour dfinir tous les fragments de votre application, mme si votre
application est excute sur HoneyComb ou plus, le systme ne switchera pas sur les fragments natifs.

V-A - Fragments natifs et Fragments de la support-library : Le parallel activity pattern

C'est la solution explique par A. Powell et B. Oliveira.

Si vous souhaitez utiliser les fragments natifs quand vous tes au-dessus d'HoneyComb et les fragments de la
support-library quand vous tes au-dessous, il vous faut mettre en place le Parallel activity pattern :

Pour cela, vous allez dclarer dans votre manifest.xml, l'activit LauncherActivity comme tant votre activit de
lancement :

1. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
2. package="com.android2ee.tuto.fragment.fragmentstatic.tuto"

- 25 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

3. android:versionCode="1"
4. android:versionName="1.0">
5.
6. <uses-sdk
7. android:minSdkVersion="8"
8. android:targetSdkVersion="15"/>
9.
10. <application
11. android:name="MApplication"
12. android:icon="@drawable/ic_launcher"
13. android:label="@string/app_name"
14. android:theme="@style/AppTheme">
15.
16. <activity
17. android:name=".LauncherActivity"
18. android:label="@string/title_activity_main">
19. <intent-filter>
20. <action android:name="android.intent.action.MAIN"/>
21. <category android:name="android.intent.category.LAUNCHER"/>
22. </intent-filter>
23. </activity>
24.
25. <activity android:name=".view.honeycomb.main.MainActivityHC">
26. </activity>
27.
28. <activity android:name=".view.legacy.main.MainActivityLegacy">
29. </activity>
30.
31. <activity android:name=".view.honeycomb.detail.DetailActivityHC">
32. </activity>
33.
34. <activity android:name=".view.legacy.detail.DetailActivityLegacy">
35. </activity>
36. </application>
37.
38. </manifest>

Vous dclarez aussi les autres activits qui peuplent votre application, comme d'habitude.

Dans l'activit LauncherActivity vous n'effectuez qu'une seule chose, vous regarder la version de l'appareil sur laquelle
s'excute votre application et en fonction de cette version, vous lancez, soit l'activit spcifique HoneyComb (avec
les fragments natifs), soit la version legacy (avec les fragments de la support-library).

Le code de l'activit est le suivant :

1. public class LauncherActivity extends Activity {


2. @Override
3. publicvoid onCreate(Bundle savedInstanceState) {
4. super.onCreate(savedInstanceState);
5. // Dfinissez l'Intent
6. Intent startActivityIntent = null;
7. // Trouvez la version (post ou pre HoneyComb)
8. boolean postHC = getResources().getBoolean(R.bool.postHC);
9.
10. // Instanciez l'Intent en fonction de cette version
11. if (postHC) {
12. startActivityIntent = new Intent(this, MainActivityHC.class);
13. } else {
14. startActivityIntent = new Intent(this, MainActivityLegacy.class);
15. }
16.
17. // Lancez l'activit :
18. startActivity(startActivityIntent);
19. // Et suicidez-vous : soyez sr de ne pas appartenir la backstack
20. finish();
21. }
22. }

- 26 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Pour connaitre la version de l'appareil, les ressources sont une fois de plus utilises et dclarent le boolen postHC
de la manire suivante :

Dans le dossier res\values, vous avez dfini le fichier version.xml :

1. <?xml version="1.0"encoding="utf-8"?>
2. <resources>
3. <bool name="postHC">false</bool>
4. </resources>

Et dans le dossier values-v11, vous avez dfini le fichier version.xml :

1. <?xml version="1.0"encoding="utf-8"?>
2. <resources>
3. <bool name="postHC">true</bool>
4. </resources>

Ainsi l'appel getResources().getBoolean(R.bool.postHC) vous renvoie auto-magiquement la version du systme


sur laquelle s'excute l'application. Et en fonction de cette version, vous lancez l'activit adapte.

Maintenant que vous avez fait a, il ne vous reste plus qu' dfinir votre activit post-HoneyComb et votre activit
pr-HoneyComb. L'activit post-HoneyComb est celle explique depuis le dbut de cet article, apprenons mettre
en place l'activit pr-HoneyComb avec la support-library.

V-A-1 - Utilisation de finish

Remarque importante : La LauncherActivity finit son code par un appel finish(), c'est essentiel. Cela signifie
l'activit qu'elle doit mourir et surtout ne pas se placer dans la backstack. En effet, si on oublie cette ligne, quand
la nouvelle activit est lance, LauncherActivity se place dans la backstack. Quand l'utilisateur quitte l'activit Main
(post ou pr-HoneyComb, cela n'a pas d'importance), cela relancera alors automatiquement LauncherActivity (car
on dpile la backstack). Et comme LauncherActivity relance MainActivity, votre utilisateur ne pourra pas sortir de
MainActivity

V-B - Mise en place des Fragments de la support-library

Tout d'abord, ajoutez la support-library votre projet : Clic droit sur le projet Android->Add Support Library (si une
erreur survient, mettre jour la support-library via le SDK manager).

V-B-1 - Migration de l'activit

1 Commencez par coder l'activit post-HoneyComb.


2 Crez votre activit pr-HoneyComb, que nous appellerons ActivityLegacy. Copiez/collez le code de l'activit
post-HoneyComb dans l'activit que vous venez de crer.
3 Modifier ActivityLegacy pour qu'elle hrite de FragmentActivity (et non plus d'Activity). Vous pouvez aussi
hriter de ActionBarActivity si vous souhaitez faire apparatre l'action bar quelle que soit la version de
l'appareil (mais c'est encore une autre histoire que je ne vous conterai pas dans cet article).
4 Puis, supprimez tous les imports de la classe ActivityLegacy et remplacez-les par ceux de la support-library.

Voil, vous avez fini.

1. import android.support.v4.app.FragmentActivity;
2.
3. public class ItemListActivity extends FragmentActivity {
4. @Override
5. public void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);

- 27 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

7. setContentView(R.layout.activity_item_list);
8. FragmentManager fm=getSupportFragmentManager() ;
9. .... blabla ....}
10. }

Un dernier dtail, la rcupration du FragmentManager s'effectue via la mthode getSupportFragmentManager (et


non plus par getFragmentManager).

V-B-2 - Migration des fragments

Pour migrer un fragment natif en fragment de la support-library, rien de plus simple, vous copiez/collez la classe du
fragment natif (celui cod pour les versions post-HoneyComb). Vous supprimez ces imports et vous les remplacez
par ceux de la support-library.

V-C - Migration des fichiers de layout

Dans le cas des fragments statiques, le fichier de layout de l'activit dclare quelle est la classe qui instancie le
fragment. Ainsi, vous devez dupliquer tous les fichiers de layout de vos activits et, pour ceux qui implmentent
les activits legacy, modifier le chemin de la classe qui implmente le fragment pour le faire pointer vers la classe
monFragmentLegacy.

Le fichier de layout main_ActivityHC.xml ressemble cela :

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical">
6.
7. <fragment
8. android:id="@+id/list_fragment"
9. android:name="com.android2ee.tuto.fragment.fragmentstatic.tuto.view.honeycomb.main.MainFragmentHC"
10. android:layout_width="fill_parent"
11. android:layout_height="fill_parent"
12. android:layout_weight="1"
13. android:orientation="horizontal">
14. </fragment>
15.
16. </LinearLayout>

Et le fichier de layout main_Activity_Legacy ressemble cela :

1. <?xml version="1.0"encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical">
6.
7. <fragment
8. android:id="@+id/list_fragment"
9. android:name="com.android2ee.tuto.fragment.fragmentstatic.tuto.view.legacy.main.MainFragmentLegacy"
10. android:layout_width="fill_parent"
11. android:layout_height="fill_parent"
12. android:layout_weight="1"
13. android:orientation="horizontal">
14. </fragment>
15.
16. </LinearLayout>

- 28 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

V-D - Duplication du code

Vous venez de mettre en place le parallel activity pattern, bravo. Maintenant regardez votre code, vous avez dupliqu
toute vos classes d'activit et de fragment En fait, vous avez fait pire, vu que dans le fichier de layout de l'activit,
la classe qui implmente le fragment est mentionne, vous avez aussi t oblig de dupliquer le fichier de layout
de vos activits.

Revenons l'exemple de Google :

Ainsi, si vous n'aviez pas mis en place le multi-versionning, votre projet ressemblerait cela :

src
ActivityA_HC
ActivityB_HC
FragmentA_HC
FragmentB_HC
res\layout-port-v11||res\layout-large-v11||res\layout-xlarge-v11
activity_a_layout_hc
res\layout
activity_a_layout_hc
activity_b_layout_hc
fragment_a_layout
fragment_b_layout

Et maintenant, avec le Parallel Activity Pattern, votre projet ressemble cela (en rouge les duplications) :

src
ActivityA_HC
ActivityB_HC
FragmentA_HC
FragmentB_HC
ActivityA_Leg
ActivityB_Leg
FragmentA_Leg
FragmentB_Leg
res\layout-port||res\layout-large||res\layout-xlarge
activity_a_layout_leg
res\layout-port-v11||res\layout-large-v11||res\layout-xlarge-v11
activity_a_layout_hc

- 29 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

res\layout
activity_a_layout_hc
activity_b_layout_hc
activity_a_layout_leg
activity_b_layout_leg
fragment_a_layout
fragment_b_layout

V-E - Conclusion concernant le multi-versionning : Use only the support-library

Le choix est donc, soit d'utiliser uniquement la support-library, soit de dupliquer votre code (Activit, layout et
Fragment) en ne changeant que les imports et le type d'animation puis d'utiliser le parallel activity pattern pour tre
le plus adapt toutes les versions du systme. Donc :

N'utilisez pas les fragments natifs, utilisez toujours la support-library !

Concrtement, ajoutez la support-library votre projet et n'utilisez que les imports de la support-library quand vous
codez votre projet. Pour le reste, vous ne verrez pas de diffrence.

VI - Fragment dynamique

Une seconde manire d'utiliser les fragments est de mettre en place une activit qui va les ajouter, les remplacer,
les supprimer dynamiquement. Ainsi, votre application ne possde qu'une activit et elle a en charge la gestion de
l'affichage des fragments.

- 30 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

L'utilisateur final ne verra aucune diffrence.

VI-A - Mise en place

La mise en place est quasi-identique celle des fragments statiques :

Vos classes de type fragment ne changent pas ;


Vos interfaces de callback ne changent pas.

Les fichiers de layout de vos activits remplacent eux, la balise fragment par un layout (LinearLayout souvent).

Cela signifie simplement qu'avant, vous aviez un layout pour votre activit qui ressemblait cela :

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android" android:layout_width="fill_parent"android:layout_height="fill_parent"
3. android:orientation="vertical" >
4.
5. <fragment
6. android:id="@+id/list"
7. android:layout_width="0dp"
8. android:layout_height="fill_parent"
9. android:layout_weight="1"
10. android:name="com.android2ee.tuto.fragment.sample1.ListFragment"
11. android:orientation="horizontal" >
12. </fragment>
13. <fragment
14. android:id="@+id/detail"
15. android:layout_width="0dp"
16. android:layout_height="fill_parent"
17. android:layout_weight="1"
18. android:name="com.android2ee.tuto.fragment.sample1.DetailFragment"
19. android:orientation="horizontal" >
20. </fragment>
21. </LinearLayout>

Avec les fragments dynamiques, votre fichier de layout ressemble a :

1. <?xml version="1.0" encoding="utf-8"?>


2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="horizontal">
6.
7. <LinearLayout
8. android:id="@+id/firstpane"
9. android:layout_width="0dp"
10. android:layout_height="fill_parent"
11. android:layout_weight="1"
12. android:orientation="horizontal">
13. </LinearLayout>
14.

- 31 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

15. <LinearLayout
16. android:id="@+id/secondpane"
17. android:layout_width="0dp"
18. android:layout_height="fill_parent"
19. android:layout_weight="1"
20. android:orientation="horizontal">
21. </LinearLayout>
22. </LinearLayout>

C'est--dire qu'ils ressemblent un bon vieux fichier de layout.

VI-B - Gestion des Fragments : FragmentManager et FragmentTransition

Maintenant, il faut savoir remplacer/ajouter ou supprimer des fragments. Cela se fait toujours de la mme manire :

Instanciation du FragmentManager et d'une FragmentTransaction ;


Ajout des animations entrantes et sortantes ;
Vrification que le fragment crer appartient (ou pas) la backstack ;
S'il n'appartient pas la backstack on le cre et on ajoute/remplace le fragment existant par celui que
l'on vient de crer,
S'il appartient la backstack :
soit on considre que l'on dpile la backstack (en d'autres termes dans votre tte, l'utilisateur a
appuy sur le bouton back), donc on pop la backstack pour afficher le fragment,
soit on considre que l'on avance dans la navigation (mme si le fragment a dj t prsent
l'utilisateur), dans ce cas on r-affiche le fragment ;
Ajout de la transaction la backstack ;
Commit de la transaction.

1. public void showAnotherFragment() {


2. // Rcuprez le FragmentManager
3. FragmentManager fm = mainActivity.getFragmentManager();
4. // Dbutez la transaction des fragments
5. FragmentTransaction fTransaction = fm.beginTransaction();
6. // Dfinissez les animations entrantes et sortantes
7. fTransaction.setCustomAnimations(R.anim.anim_push_left_in,
8. R.anim.anim_push_left_out,
9. R.anim.anim_push_left_in,
10. R.anim.anim_push_left_out);
11. // Trouvez si le fragment afficher existe dj
12. AnotherFragmentHC eventsListFragment = (AnotherFragmentHC)
fm.findFragmentByTag(anotherFragmentTag);
13. // Si le fragment n'existe pas, il faut le crer
14. if (eventsListFragment == null) {
15. eventsListFragment = new EventsListFragmentHC();
16. // Ajoutez le nouveau fragment (Dans ce cas prcis, un fragment est dj affich cet emplacement, il faut d
17. fTransaction.replace(R.id.mainfragment, eventsListFragment, anotherFragmentTag);
18. }else{
19. // Le fragment existe dj, il vous suffit de l'afficher
20. fTransaction.show (eventsListFragment);
21. }
22. // Ajoutez la transaction la backstack pour la dpiler quand l'utilisateur appuiera sur back
23. fTransaction.addToBackStack(mainActivity.getString(R.string.main_htitle));
24. // Fates le commit
25. fTransaction.commit();
26. }

Remarquez que nous n'utilisons plus les identifiants des fragments mais leur tag, en effet, vous n'avez plus la
possibilit de leur donner un identifiant.

- 32 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

VI-C - Initialisation

Lors de l'initialisation, il faut tre attentif au cas de recration de l'activit pour ne pas instancier plusieurs fois le
fragment. En effet, les fragments sont automatiquement restaurs (bien que dtruit entre temps, cela n'a rien voir
avec le RetainInstance qui lui, ne dtruit pas le fragment et ne s'applique qu'aux fragments sans I.H.M., rappelons-le).

1. public class MainActivity extendsActivity {


2.
3. private String ListFragmentTag = "listfragmenttag";
4.
5. @Override
6. public void onCreate(Bundle savedInstanceState) {
7. super.onCreate(savedInstanceState);
8. setContentView(R.layout.main);
9. //Cependant, si le fragment est restaur partir d'un tat prcdent, alors il n'y a pas besoin d'effectuer q
10. if (savedInstanceState == null) {
11. // Rcuprez le FragmentManager
12. FragmentManager fm = getFragmentManager();
13. // Trouver si le fragment que nous souhaitons afficher appartient la backstack
14. ListFragment firstFragment = (ListFragment) fm.findFragmentByTag(ListFragmentTag);
15. if (null == firstFragment) {
16. // Crez le fragment
17. firstFragment = new ListFragment();
18. }
19.
//Dans notre cas, l'activit a t dmarre avec des paramtres spcifiques contenus dans l'Intent. Passez ces p
20. firstFragment.setArguments(getIntent().getExtras());
21. // Ajoutez le fragment son layout et effectuez le commit
22. fm.beginTransaction().add(R.id.myListView, firstFragment).commit();
23. }
24. }
25. }

VI-C-1 - Passage de paramtres lors de la cration du fragment

Pour instancier un fragment en lui passant des paramtres, il suffit d'utiliser la mthode setArguments.

1. Bundle arguments = new Bundle();


2. arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
3. ItemDetailFragment fragment = new ItemDetailFragment();
4. fragment.setArguments(arguments);

Le fragment n'a plu qu' appeler la mthode getArguments (n'importe o dans son code) pour rcuprer le bundle
associ sa cration.

1. if (getArguments().containsKey(ARG_ITEM_ID)) {
2. mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
3. }

Pour information, avec une activit on utilise le setExtras et le getIntent().getExtras.

VI-C-2 - Bonne pratique du cas particulier de la rotation de l'appareil

Le corollaire de cette restauration automatique des fragments lors de la destruction/recration de l'activit est la
bonne pratique suivante :

Tous vos layouts dclins en mode landscape-portrait doivent avoir les mmes layout containers mme s'ils ne sont
pas utiliss.

- 33 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

En d'autres termes, votre activit affiche 2 fragments dans le mode landscape et un seul en mode portrait (ou vice-
versa), vous devez dclarer les 2 LinearLayouts pour recevoir les deux fragments dans les deux fichiers xml de layout
de l'activit. C'est--dire :

res\layout\main_layout.xml

(Un seul fragment)

1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. ... blabla ...>
3. <FrameLayout android:id="@+id/item_list_container"
4. android:layout_width="0dp"
5. android:layout_height="match_parent"/>
6.
7. <FrameLayout android:id="@+id/item_detail_container"
8. android:layout_width="0dp"
9. android:layout_height="match_parent"
10. android:visibility="gone" />
11. </LinearLayout>

res\layout-land\main_layout.xml

(Deux fragments)

1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. ... blabla ...>
3. <FrameLayout android:id="@+id/item_list_container"
4. android:layout_width="0dp"
5. android:layout_height="match_parent"/>
6.
7. <FrameLayout android:id="@+id/item_detail_container"
8. android:layout_width="0dp"
9. android:layout_height="match_parent"
10. />
11. </LinearLayout>

Si vous ne faites pas a, vous ne restaurerez pas le second fragment dans le cas de la destruction/recration de
votre activit deux fois de suite :

Deux rotations de l'appareil : land -> port -> land (2 fragment non restaur).

Notez que cette bonne pratique ne s'applique quasiment qu'au cas landscape/portrait. En effet, il est rare de changer
la taille ou la densit d'un appareil au run-time.

VI-D - Structurer une application possdant des fragments

Revenons concrtement l'exemple de Google sur les fragments :

- 34 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Il y a l'activit A qui possde un ou deux fragments en fonction de son contexte d'excution. Le fragment A affiche
une liste, le fragment B affiche l'item de la liste slectionn.

VI-D-1 - Design Pattern

En fait le, principe est le suivant :

L'activit A connait les fragments qu'elle contient. Les fragments ne connaissent pas leur conteneur, mais uniquement
leur CallBack. Ces callbacks ne sont plus implments par l'activit elle-mme mais par une classe FragmentSwitcher
dans laquelle on a dport le code de gestion des fragments.

Le FragmentSwitcher a en charge l'orchestration de ses fragments, elle les coute, les met jour, les supprime et
les cre. C'est elle de passer l'information de l'un l'autre ou de changer les fragments (cas dynamique).

- 35 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

VI-D-2 - La mthode onItemSelected de l'activit A

Ainsi dans l'exemple de Google, le fragment A appelle l'activit A (via le onItemSelected de l'interface
FragmentACallBack). L'activit A doit alors connaitre son contexte ; si elle affiche deux fragments, elle doit mettre le
second fragment jour, si elle n'affiche qu'un fragment, elle doit afficher le fragment B (et donc le crer).

En code cela donne :

1. /***********************************************************************/
2. /** OnItemSelection Management *******************************************/
3. /**********************************************************************/
4. /* * (non-Javadoc) *
5. * @see com.android2ee.tuto.fragment.fragment.dynamic.tuto.view.callback.MainFragmentCallBack#
6. * onItemSelected(int) */
7. @Override
8. public void onItemSelected(int itemId) {
9. // Ok le moment du choix
10. //En fonction du nombre de fragments affichs, soit detailFragment doit tre mis jour, soit il faut changer
11. if (twoPanes) {
12. onItemSelectedTwoPanes(itemId);
13. } else {
14. onItemSelectedOnePane(itemId);
15. }
16. }
17. /**
18. * OnPane Management
19. * Gestion du cas o il n'y a qu'un layout
20. * @param itemIdthe item to display
21. */
22. public void onItemSelectedOnePane(int itemId) {
23. // Ne conservez jamais une rfrence vers un fragment en vue de le r-instancier
24. // (DetailFragmentHC) fm.findFragmentByTag (detailFragmentFPTag) devrait tre nul
25. // Nous avons besoin de le crer puis de l'ajouter au layout
26. // En effet Soit il n'a pas t cr (premire cration)
27. // Soit il a t dtruit (cr puis backstack.popup appel)
28. // Dans tous les cas, il n'existe plus
29.
30. // Trouver le gestionnaire de fragment
31. FragmentManager fm = activity.getFragmentManager();
32. DetailFragmentHC detailFragmentFirstPane = (DetailFragmentHC)
fm.findFragmentByTag(detailFragmentFPTag);
33. if (null == detailFragmentFirstPane) {
34. //Comportement normal
35. detailFragmentFirstPane = new DetailFragmentHC();
36. //Ajoutez la position de l'item en argument de cration du fragment
37. //Utilisez le pattern de l'argument
38. Bundle bundle = new Bundle();
39. bundle.putInt(DetailFragmentHC.ITEM_ID, itemId);
40. detailFragmentFirstPane.setArguments(bundle);
41. //Remplacez mainFragment par detailFragment
42. FragmentTransaction fTransaction = fm.beginTransaction();
43. // Dfinissez les animations
44. fTransaction.setCustomAnimations(R.anim.anim_push_left_in,
45. R.anim.anim_push_left_out,
46. R.anim.anim_push_right_in,
47. R.anim.anim_push_right_out);
48. // Remplacez, ajoutez la backstack et commit
49. fTransaction.replace(R.id.firstpane, detailFragmentFirstPane, detailFragmentFPTag);
50. fTransaction.addToBackStack(activity.getString(R.string.main_fragment));
51. fTransaction.commit();
52. }
53. }
54. /**
55. * TwoPane Management
56. * Gestion du cas o il y a deux layouts
57. * @param itemIdthe item to display
58. */
59. public void onItemSelectedTwoPanes(int itemId) {
60. // Trouvez le FragmentManager

- 36 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

61. FragmentManager fm = activity.getFragmentManager();


62. // Le fragment existe et a dj t ajout au layout
63. // Ainsi, retrouvez le et mettez le juste jour
64. DetailFragmentHC detailFragmentSecondPane = (DetailFragmentHC)
fm.findFragmentByTag(detailFragmentSPTag);
65. // Mise jour donc :
66. detailFragmentSecondPane.updateData(itemId);
67. }

VI-D-3 - La classe FragmentsSwitcher

Pour une activit qui met en place des fragments dynamiquement, il est une bonne pratique qui consiste extraire de
l'activit tout le code correspondant la gestion des fragments dans une classe part ddie cette problmatique.
Cette classe n'est autre que le FragmentSwitcher (vous pouvez l'appeler comme bon vous semble).

Ainsi, vous centralisez dans le FragmentSwitcher toute votre gestion des fragments. La classe FragmentSwitcher
implmente tous les callbacks des fragments qu'elle gre.

Vous pouvez avoir plusieurs FragmentSwitchers pour une mme activit. Par exemple, FragmentSwitcherHuman
pour grer les fragments affichant les humains, FragmentSwitcherDroid pour les fragments affichant les droids. Cela
permet la navigation de changer de contexte de fragments plutt que de lancer une nouvelle activit pour afficher
les droids.

Enfin, cela permet l'activit de se concentrer sur ce dont elle est responsable : cycle de vie, coute des Intents

La liaison Activity-FragmentSwitcher est de type 1 - [0 ,1]. L'activit possde un ou 0 FragmentSwitcher, le


FragmentSwitcher possde toujours une activit.

Les fragments ne connaissent plus l'activit mais uniquement le FragmentSwitcher.

VI-D-4 - Fragments et BackStack

Il est naturel que certains fragments soient considrs comme des activits d'un point de vue utilisateur et que
l'appui sur le bouton back raffiche le fragment prcdemment affich. En effet, pour l'utilisateur, lancer une nouvelle
activit ou afficher un nouveau fragment est pour lui transparent. Il doit donc pouvoir dpiler sa navigation au sein
des fragments comme il le faisait avec les activits.

Pour mettre en place ce mcanisme, il suffit d'ajouter le fragment la backstack.

1. // Ajoutez le fragment
2. fTransaction.replace(R.id.mainfragment, eventsListFragment, eventsListFragmentTag);
3. // Ajoutez la transaction la backstack
4. fTransaction.addToBackStack(mainActivity.getString(R.string.main_htitle));
5. // Fates le commit
6. fTransaction.commit();

En fait, ce n'est pas le fragment qui est ajout la backstack, mais la transaction. Quand la backstack sera dpile,
la transaction sera inverse. Plus subtilement, cela signifie aussi que le fragment est conserv dans la backstack et
dpiler la backstack le restaurera. Cela signifie au niveau du cycle de vie du fragment un petit changement.

Quand on supprime ou l'on remplace un fragment et qu'on le dpose dans la backstack :

Les mthodes onPause, onStop et onDestroyView sont appeles sur le fragment quand il est plac dans la
backStack.
Et les mthodes onCreateView, onActivityCreated, onStart et onResume quand il en est dpil.

Placer un fragment dans la backstack impacte le cycle de vie du fragment.

- 37 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

VI-D-4-a - Backstack : ne la supposez pas

Quand on manipule les fragments dynamiquement, il est toujours ncessaire de savoir o on en est ; quel est l'tat
de la backstack, quels sont les fragments instancis, dtruits.

En effet, quand on affiche ou raffiche un fragment, le choix de la mthode show, add ou replace est primordial, de
mme que l'appel aux mthodes addToBackstack et popBackstack.

Pourtant, sur un simple exemple, s'il l'on considre le diagramme d'tat de la backstack, on voit qu'il nous est
impossible de prvoir l'tat de la backstack :

Ainsi, au lieu d'imaginer que l'on sait quel est l'tat de la backstack, il nous faut la requter et, en fonction du rsultat,
faire un popBackStack, un ajout, un replace ou un show du fragment. C'est la bonne pratique Toujours interroger
la backstack avant d'instancier un fragment explique plus bas dans l'article.

VI-D-5 - Nombre de fragments affichs et structuration des layouts.

De la mme manire que pour la gestion statique des fragments, vous allez mettre en place le systme des
redirections de vos layouts avec les fichiers du type :

1. <resources>
2. <itemname="main_activity"type="layout">@layout/activity_two_panes</item>
3. <boolname="twoPane">true</bool>
4. </resources>

L'objectif est de toujours connatre le nombre de fragments affichs l'cran et de centraliser vos fichiers de layout
dans res\layout.

VI-E - Navigation

Il y a quatre manires de mettre en place une navigation dans une application Android.

- 38 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Les six packs Navigation par onglets Navigation Navigation avec le


avec un spinner Navigation Drawer

Ce qu'il vous faut comprendre, d'un point de vue dveloppement, c'est que c'est de la cosmtique pour les utilisateurs
finaux. Pour vous, la navigation se rsume mettre un composant graphique en place avec un listener permettant
l'utilisateur de faire un choix.

En fonction de ce choix, vous pouvez :

filtrer vos donnes ;


changer de fragment ;
changer de contexte de fragments ;
lancer une nouvelle activit ;
effectuer n'importe quelle action qui affiche de nouvelles donnes l'utilisateur.

Si vous voulez en savoir plus sur le sujet, vous pouvez venir aux formations Android2EE, je vous explique beaucoup,
beaucoup plus de choses concernant la mise en place d'applications Android, les bonnes pratiques respecter et
tout ce qu'il faut savoir pour russir le dveloppement d'une application Android. En particulier la mise en place de
la navigation via l'ActionBar (l'ActionBarCompat pour tre exact).

VI-F - Animations

Les animations sont importantes pour permettre l'utilisateur de comprendre la dynamique de votre application.
L'esprit humain comprend beaucoup mieux les changements de contexte avec une animation de transition que sans.
C'est l'objectif principal des animations.

Les animations ajoutent aussi une touche de beaut votre application, ce qui amliore l'exprience utilisateur.

Je ne rentrerai pas dans les dtails, si vous souhaitez un approfondissement, comme je viens de vous le dire, venez
mes formations je vous l'expliquerai plus longuement.

Concernant les animations, les points cruciaux sont :

MinSDK=11 ?o? Utiliser le parallel pattern.

Deux types d'animation incompatibles : Avant (TweenAnimation) Aprs (ObjectAnimator, ViewProperty) HoneyComb

Soyez courts.

Le temps d'animation par dfaut est de 300 ms.

Cela dpend de l'objet animer (une vue, une activit, ce n'est pas un bouton).

Soyez poustouflant mais une fois.

Les animations longues, belles et dlirantes deviennent ennuyeuses au bout de trois.

Remplacez-les par des animations efficaces au bout de trois.

Si, en dveloppement, votre animation ne vous pourrit pas la vie, alors elle ne pourrira pas celle de vos utilisateurs.

- 39 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

Thanks Chet.

Depuis HoneyComb, les animations sont amliores, simplifies et super flexibles.

Dev.Bytes nous poste des tutoriaux de 3 minutes pour nous les apprendre.

Merci Chet pour tout a.

VI-F-1 - Mise en place des animations

Pour mettre en place les animations lors des transitions entre les fragments, vous tes obligs d'utiliser le parallel
activity pattern tendu.

Il vous faut vrifier quelle est la version de l'appareil sur laquelle s'excute votre application. Si cette version est
infrieure HoneyComb vous devez utiliser les TweenAnimations, si elle est suprieure HoneyComb, vous mettrez
en place les ObjectAnimators.

Vous allez donc avoir deux dossiers anim et anim-v11 possdant les mmes fichiers (par exemple monAnim.xml)
mais dans anim, vous utiliserez les TweenAnimation et dans anim-v11 vous utiliserez les ObjectAnimator.

Ainsi vous aurez les fichiers suivants :

res\anim\anim_push_left.xml

1. <?xml version="1.0" encoding="utf-8"?>


2. <set xmlns:android="http://schemas.android.com/apk/res/android">
3.
4. <translate
5. android:duration="500"
6. android:fromXDelta="100%p"
7. android:toXDelta="0"/>
8.
9. <alpha
10. android:duration="500"
11. android:fromAlpha="0.0"
12. android:toAlpha="1.0"/>
13.
14. <scale
15. android:duration="500"
16. android:fromXScale="0.0"
17. android:fromYScale="0.0"
18. android:pivotX="50%"
19. android:pivotY="50%"
20. android:toXScale="1.0"
21. android:toYScale="1.0"/>
22.
23. </set>

res\anim-v11\anim_push_left.xml

1. <?xmlversion="1.0"encoding="utf-8"?>
2. <setxmlns:android="http://schemas.android.com/apk/res/android">
3.
4. <objectAnimator
5. android:duration="1000"
6. android:propertyName="translationX"
7. android:valueFrom="-250"
8. android:valueTo="0"
9. android:valueType="floatType"/>
10.
11. <objectAnimator
12. android:duration="1000"

- 40 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

13. android:propertyName="scaleX"
14. android:valueFrom="0.0"
15. android:valueTo="1.0"
16. android:valueType="floatType"/>
17.
18. <objectAnimator
19. android:duration="1000"
20. android:propertyName="scaleY"
21. android:valueFrom="0.0"
22. android:valueTo="1.0"
23. android:valueType="floatType"/>
24.
25. <objectAnimator
26. android:duration="1000"
27. android:propertyName="rotationY"
28. android:valueFrom="0"
29. android:valueTo="360"
30. android:valueType="floatType"/>
31.
32. </set>

VI-G - Bonnes pratiques

VI-G-1 - Toujours interroger la backstack avant d'instancier un fragment avec findByTag

1. //La mthode findByTag (resp. findById) trouve un fragment qui a t identifi par la balise
2. //donne (lorsqu'il est gonfl partir de XML ou fourni lorsqu'il est ajout une transaction).
3. //La recherche s'effectue d'abord dans les fragments qui sont actuellement grer par l'activit ; si
4. //aucun fragment ne s'y se trouve, alors la recherche continue parmi tous les fragments
5. //actuellement dans la backstack.
6. //Ainsi, s'il n'est pas trouv, il faut le crer.
7. MainFragmentHC mainFragment;
8. mainFragment = (MainFragmentHC) fm.findFragmentByTag(mainFragmentTag);
9. if (null == mainFragment) {
10. // Crez le fragment
11. mainFragment = new MainFragmentHC();
12. // Ajoutez le ou remplacer un fragment existant par celui-ci.
13. fTransaction.add(R.id.firstpane, mainFragment, mainFragmentTag);
14. } else {
15. // MainFragment appartient soit la vue actuelle, soit la backStack
16. // Si elle appartient la vue actuelle : ne rien faire est la chose faire
17. // Si elle appartient la backStack : faire un pop de la backstack pour l'afficher est la
18. //chose faire.
19. // Donc, on fait un pop de la backstack si Pop_BackStackInclusive vous faites un pop de la transaction avec l
20.
fm.popBackStackImmediate(activity.getResources().getString(R.string.main_fragment),FragmentManager.POP_BACK_STACK
21. // Maintenant nous sommes srs que s'il tait dans la backstack, il a t ramen au
22. // devant de la scne
23. // Donc l'afficher est suffisant
24. fTransaction.show(mainFragment);
25. }

VI-G-2 - Autres bonnes pratiques

VI-G-2-a - Le fragment est li au layout qui le contient

Lorsque vous placez dynamiquement un fragment dans un layout, vous ne pouvez plus le placer dans un autre
layout. Concrtement, vous avez ajout le fragment myFragment avec le tag myFrag au layout dont l'identifiant est
layout_panel1. Si vous souhaitez ajouter myFragment (la mme instance) avec le tag myFrag au sein d'un autre
layout (par exemple celui avec l'identifiant layout_panel2), cela gnrera une exception au RunTime. Vous serez
oblig de crer une nouvelle instance de votre fragment et de l'ajouter au layout layout_panel2 en utilisant un autre
tag, par exemple myFrag2.

- 41 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

VI-G-2-b - Ne jamais r-instancier un fragment avec une rfrence obsolte

C'est une erreur grave que de garder un pointeur vers un fragment et d'essayer de le rutiliser au lieu d'instancier
de nouveau le fragment.

Vous pouvez garder un pointeur vers un fragment, mais assurez-vous que celui-ci suit bien le cycle de vie du fragment,
quand le fragment est dtruit votre pointeur doit tre null.

VI-G-2-c - Toujours utiliser les tags des fragments pour les identifier et les retrouver

Je n'ai rien ajouter au titre.

VII - Autres fragments

Je ne vous prsenterai que succinctement DialogFragment et PreferenceFragment.

VII-A - DialogFragment

Vous savez mettre en place des fentres de dialogue ? Eh bien vous savez aussi mettre en place des DialogFragment,
car c'est identique.

Pour afficher une fentre de dialogue vous faites :

new MyDialogFragment().show(getSupportFragmentManager(),MY_DIALOG_FRAGMENT_TAG);

Et pour dfinir la fentre de dialogue, il vous suffit de crer une classe qui tend DialogFragment et de surcharger la
mthode onCreateDialog. Dans la mthode onCreateDialog vous faites exactement comme vous faisiez avant.

1. public classMyDialogFragment extends DialogFragment {


2. @Override
3. public Dialog onCreateDialog(Bundle savedInstanceState) {
4. // Cration de l'AlertDialog Builder
5. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
6. // Titre et message
7. builder.setMessage(R.string.dialog_google_att_message);
8. builder.setTitle(R.string.dialog_google_att_title);
9. // Pas de bouton cancel
10. builder.setCancelable(false);
11. // Dfinition du bouton OK
12. builder.setPositiveButton(getString(R.string.dialog_google_att_btn), null);
13. // Cration et renvoie de l'AlertDialog
14. return builder.create();
15. }
16. }

VII-B - PreferenceFragment

Comme pour les DialogFragments, si vous saviez le faire avant (avec les PreferenceActivity), vous savez le
faire avec les fragments. La seule diffrence est que vous allez crer une classe MyPrefsFragment qui hrite de
PreferenceFragment et vous surchargerez sa mthode onCreate ainsi :

1. public static class PrefsFragment extends PreferenceFragment {


2.
3. @Override
4. publicvoid onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6.

- 42 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/
Tutoriel Android : tout comprendre sur les Fragments par Mathias Seguy

7. // Charger les prfrences partir du XML


8. addPreferencesFromResource(R.xml.preferences);
9. }
10. }

O R.xml.preferences pointe vers votre fichier xml de prfrences.

VIII - Conclusion

A l'heure actuelle, vous ne pouvez plus effectuer de dveloppement Android sans utiliser les fragments. J'espre que
cet article vous a plu et vous a permis de comprendre le fonctionnement des fragments et leur mise en place.

J'espre aussi vous retrouver en formation pour pouvoir vous expliquer durant 5 jours quelles sont les bonnes
pratiques de dveloppement Android, les architectures mettre en place, la gestion des ressources et bien plus
encore. En formation, c'est un classeur de 500 pages que je vous explique et avec lequel vous repartez, ainsi que
plus de 70 tutoriels que vous pourrez utiliser librement.

Alors vos Fragments et ActionBars and may the force be with you !

IX - Remerciements

J'adresse ici tous mes remerciements Feanorin pour son implication, son aide et sa sympathie et Phanloga
pour ses corrections orthographiques ainsi que F-Leb et Mickael Baron pour la mise au gabarit du document.

- 43 -
Copyright 2014 Mathias Seguy. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents,
images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' trois ans de prison et jusqu' 300 000 de dommages et intrts.
http://mathias-seguy.developpez.com/tutoriels/android/comprendre-fragments/

You might also like