Newsletter Developpez.com

Inscrivez-vous gratuitement au Club pour recevoir
la newsletter hebdomadaire des développeurs et IT pro

Tutoriel sur l'utilisation des fragments sous Android

Cet article décrit comment utiliser la classe Fragment dans une application Android pour créer des mises en page avec plusieurs panneaux, par exemple des applications qui se dimensionnent automatiquement par rapport au périphérique. Cet article se base sur Eclipse 4.3 (Kepler), Java 1.6 et Android 4.3.

Nous remercions Lars Vogel qui nous a aimablement autorisés à traduire et héberger cet article.

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Article lu   fois.

Les deux auteur et traducteur

Site personnel

Traducteur : Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Les bases d'Android

La suite de cet article suppose que vous avez déjà une connaissance basique du développement sous Android.

2. Les fragments

2-1. Qu'est ce qu'un fragment ?

Un fragment est un composant indépendant qui peut être utilisé dans une activité. Un fragment encapsule des fonctionnalités qui le rendent facile à réutiliser dans une activité ou dans une mise en page.

Un fragment s'exécute dans le contexte d'une activité mais possède son propre cycle de vie et typiquement, il possède une interface utilisateur. Il est aussi possible de définir des fragments sans interface utilisateur, par exemple des fragments sans entête.

Les fragments peuvent être ajoutés à une activité de manière statique ou dynamique.

2-2. Avantages de l'utilisation des fragments

Les fragments permettent une réutilisation plus facile dans différentes mises en page. Par exemple, vous pouvez construire des mises en page avec un seul panneau pour des téléphones et plusieurs panneaux pour des tablettes. Ce n'est pas limité aux tablettes, vous pouvez aussi supporter les différentes mises en page suivant l'orientation (portrait ou paysage) du téléphone.

L'exemple typique est une liste dans une activité. Sur une tablette vous pouvez voir les détails immédiatement sur la partie droite si vous cliquez sur un élément. Sur un téléphone, vous affichez une nouvelle fenêtre avec les détails. Ceci est représenté par le schéma suivant :

Image non disponible

La discussion suivante suppose que vous avez deux fragments (principal et détail) mais vous pouvez aussi en avoir plus. Nous aurons aussi une activité principale et une activité détaillée. Sur une tablette, l'activité principale contient les deux fragments dans sa mise en page, sur un téléphone, elle ne contient que l'activité principale.

Le schéma suivant montre cette utilisation :

Image non disponible

2-3. Comment utiliser les fragments ?

Pour créer différentes mises en page avec des fragments, vous pouvez :

  • utiliser une activité qui affiche deux fragments sur les tablettes et un seul sur les téléphones. Dans ce cas, vous basculerez les fragments dans l'activité en cas de besoin. Cela requiert que le fragment ne soit pas déclaré dans le fichier de mise en page de manière à ce qu'il puisse être supprimé de façon dynamique. Cela requiert aussi des modifications dans la barre d'actions si le statut de la barre d'actions dépend du fragment affiché.
  • utiliser des activités séparées pour héberger chacun des fragments sur un téléphone. Par exemple quand l'interface utilisateur d'une tablette utilise deux fragments dans une activité, utilisez la même activité pour un téléphone mais en fournissant une mise en page alternative qui ne comprend qu'un seul fragment. Quand vous devez changer de fragment, vous démarrez une autre activité qui héberge l'autre fragment.

La deuxième approche est la plus flexible et en général la méthode privilégiée pour utiliser des fragments. Dans ce cas, l'activité principale vérifie que le fragment détaillé est disponible dans la mise en page. S'il est présent, l'activité principale l'informe de se mettre à jour. Si le fragment détaillé n'est pas présent, l'activité principale démarre l'activité détaillée.

3. Définir et utiliser des fragments

3-1. Définir des fragments

Pour définir un nouveau fragment, vous surchargez soit la classe android.app.Fragment soit une de ses sous-classes, par exemple ListFragment, DialogFragment, PreferenceFragment or WebViewFragment. Le code suivant vous montre un exemple d'implémentation :

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class DetailFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rssitem_detail,
        container, false);
    return view;
  }

  public void setText(String item) {
    TextView view = (TextView) getView().findViewById(R.id.detailsText);
    view.setText(item);
  }
}

3-2. Ajouter un fragment de manière statique

Pour utiliser votre nouveau fragment, vous pouvez l'ajouter de manière statique au fichier de mise en page XML.

Pour vérifier si le fragment est présent dans votre mise en page, vous pouvez utiliser la classe FragmentManager.

 
Sélectionnez
DetailFragment fragment = (DetailFragment) getFragmentManager().
   findFragmentById(R.id.detail_frag);
if (fragment==null || ! fragment.isInLayout()) {
  // start new Activity
  }
else {
  fragment.update(...);
}

Si un fragment est défini dans le fichier XML, l'attribut android:name indique le nom de la classe correspondante.

3-3. Cycle de vie d'un fragment

Un fragment possède son propre cycle de vie mais il est toujours connecté au cycle de vie de l'activité qui l'utilise.

La méthode onCreate() est appelée après l'appel à la méthode onCreate() de l'activité mais avant la méthode onCreateView() du fragment.

La méthode onCreateView() est appelée par Android dès que le fragment doit créer son interface utilisateur. Ici, vous pouvez afficher la mise en page avec la méthode inflate() ou l'objet Inflator passé en paramètre à cette méthode. Il n'y a aucun besoin d'implémenter cette méthode pour les fragments sans en-tête.

La méthode onActivityCreated() est appelée après la méthode onCreateView() quand l'activité est créée. Ici vous pouvez instancier les objets qui nécessitent un objet Context.

Les fragments ne sous classent pas le Context. Vous devez utiliser la méthode getActivity() pour obtenir l'activité parente.

La méthode onStart() est appelée une fois que le fragment devient visible.

Si une activité s'arrête, ses fragments sont aussi arrêtés. Si une activité est détruite, ses fragments sont aussi détruits.

3-4. Communication entre l'application et les fragments

Pour améliorer la ré-utilisabilité, les fragments ne devraient pas communiquer directement entre eux. Toutes les communications avec les fragments devraient se faire via l'activité qui les héberge.

Pour cela, un fragment devrait définir une interface comme un type interne pour imposer à l'activité qui veut l'utiliser d'implémenter cette interface. Ceci permet d'éviter que le fragment connaisse l'activité qui l'utilise. Dans la méthode onAttach(), le fragment peut vérifier que l'activité implémente cette interface.

Par exemple, si un fragment doit communiquer une valeur à son activité, cela peut être fait de cette façon :

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class MyListFragment extends Fragment {

  private OnItemSelectedListener listener;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rsslist_overview,
        container, false);
    Button button = (Button) view.findViewById(R.id.button1);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        updateDetail();
      }
    });
    return view;
  }

  public interface OnItemSelectedListener {
    public void onRssItemSelected(String link);
  }

  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof OnItemSelectedListener) {
      listener = (OnItemSelectedListener) activity;
    } else {
      throw new ClassCastException(activity.toString()
          + " must implemenet MyListFragment.OnItemSelectedListener");
    }
  }

  @Override
  public void onDetach() {
    super.onDetach();
    listener = null;
  }

  // May also be triggered from the Activity
  public void updateDetail() {
    // create a string, just for testing
    String newTime = String.valueOf(System.currentTimeMillis());

    // Inform the Activity about the change based
    // interface defintion
    listener.onRssItemSelected(newTime);
  }
}

4. Données persistantes dans les fragments

4-1. Données persistantes entre deux redémarrages de l'application

Avec les fragments, vous pouvez aussi avoir besoin de stocker des données applicatives. Pour cela, vous pouvez stocker ces données de manière centralisée. Par exemple :

  • dans une base de données Sqlite ;
  • dans un fichier ;
  • dans l'objet application. Dans ce cas, l'application doit supporter ce type de stockage.

4-2. Données persistantes entre deux changements de configuration

Si vous devez stocker des données de configuration, vous pouvez aussi utiliser l'objet application.

En plus, vous pouvez utiliser la méthode setRetainState(true) sur le fragment. Cela sauvegarde l'instance du fragment entre deux changements de configuration mais cela marche uniquement si le fragment n'est pas ajouté à la pile des tâches de fond (backstack). Cette méthode n'est pas recommandée par Google pour les fragments qui possèdent une interface utilisateur. Dans ce cas, les données doivent être stockées comme des membres (champs).

Si les données qui doivent être sauvegardées sont supportées par la classe Bundle, vous pouvez utiliser la méthode onSaveInstanceState() pour mettre ces données dans le Bundle et les retrouver dans la méthode onActivityCreated().

5. Modifier les fragments dynamiquement

Les classes FragmentManager et FragmentTransaction vous permettent d'ajouter, de supprimer et de remplacer des fragments dans la mise en page de votre activité.

Les fragments peuvent être modifiés dynamiquement avec des transactions. Pour ajouter dynamiquement des transactions à une mise en page déjà existante, vous définissez un container dans le fichier XML dans lequel vous pouvez ajouter le fragment. Pour cela, vous pouvez utiliser l'élément FrameLayout.

 
Sélectionnez
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.your_placehodler, new YourFragment());
ft.commit();

Un nouveau fragment va remplacer un fragment existant qui a été préalablement ajouté au container.

Si vous voulez ajouter une transition sur la pile des tâches de fond Android (backstack) vous devez utiliser la méthode addToBackStack(). Ceci rajoute l'action dans l'historique de la pile de l'activité et vous pourrez annuler les changements effectués sur le fragment avec le bouton « Back ».

6. Animation des transitions de fragments

Durant une transition de fragment, vous pouvez définir des animations basées sur l'API « Property Animation » avec la méthode setCustomAnimations().

Vous pouvez aussi utiliser les animations standard fournies par Android avec la méthode setTransition(). Elles sont définies avec les constantes commençant par FragmentTransaction.TRANSIT_FRAGMENT_*.

Ces deux méthodes permettent de définir une animation en début et en fin.

7. Ajouter des transitions de fragments sur la pile des tâches de fond (backstack)

Vous pouvez ajouter une FragmentTransition à la pile des tâches de fond (backstack) pour permettre à l'utilisateur d'utiliser le bouton « back » pour annuler la transition.

Pour cela, il faut utiliser la méthode addToBackStack() sur l'objet FragmentTransition.

8. Fragments pour les traitements en tâche de fond

8-1. Fragments sans en-tête

Les fragments peuvent être utilisés sans définir d'interface utilisateur.

Pour créer un fragment sans entête, il faut tout simplement retourner NULL dans la méthode onCreateView() de votre fragment.

Il est recommandé d'utiliser des fragments sans entête pour le traitement en tâche de fond en combinaison avec la méthode setRetainInstance(). De cette manière, vous n'avez pas à gérer vous-même les changements durant le traitement asynchrone.

8-2. Mémoriser les fragments sans en-tête pour gérer les changements de configuration

Les fragments sans en-tête sont typiquement utilisés pour mémoriser un état avant des changements de configuration ou alors pour des traitements en tâche de fond. Pour cela, vous devez mémoriser votre fragment sans en-tête. Un fragment mémorisé n'est pas détruit lors des changements de configuration.

Image non disponible

Pour mémoriser votre fragment, il faut appeler sa méthode setRetainInstance().

Pour ajouter un tel fragment à votre activité, il faut utiliser la méthode add de la classe FragmentManager. Si vous devez vous référer à ce segment plus tard, vous devez l'ajouter avec un tag de façon à pouvoir le retrouver ultérieurement avec la méthode findFragmentByTag() de la classe FragmentManager.

L'usage de onRetainNonConfigurationInstance() est obsolète et devrait être remplacé par un fragment sans entête.

9. Contribuer à la barre d'actions

Les fragments peuvent aussi influer sur la barre d'actions. Pour cela, appelez setHasOptionsMenu() dans la méthode onCreate() du fragment. Dans ce cas, le système Android appelle la méthode onCreateOptionsMenu() du fragment et ajoute les options du menu à celles déjà ajoutées par l'activité.

10. Exercice avec les fragments

10-1. Présentation

Le tutoriel suivant montre comment utiliser les fragments. L'application utilise une mise en page différente avec des fragments dépendant du mode portrait ou paysage.

Dans le mode portrait, l'activité RssfeedActivity montre un seul fragment. Depuis ce fragment, l'utilisateur peut naviguer vers une autre activité qui contient un autre fragment.

Dans le mode paysage, l'activité RssfeedActivity montre les deux fragments côte à côte.

10-2. Création du projet

Créez un nouveau projet Android avec les données suivantes :

Propriété Valeur
Nom de l'application RSS Reader
Nom du projet com.example.android.rssfeed
Nom du paquetage com.example.android.rssfeed
Modèle BlankActivity
Activité RssfeedActivity
Mise en page activity_rssfeed

Table 1. Android project

10-3. Création des mises en page

Créez ou modifiez le fichier de mise en page dans le répertoire res/layout/.

Créez un nouveau fichier de mise en page nommé fragment_rssitem_detail.xml. Ce fichier de mise en page sera utilisé par le fragment DetailFragment.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/detailsText"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal|center_vertical"
        android:layout_marginTop="20dip"
        android:text="Default Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textSize="30dip" />

</LinearLayout>

Créez un nouveau fichier de mise en page nommé fragment_rsslist_overview.xml. Ce fichier de mise en page sera utilisé par le fragment MyListFragment.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Press to update"
         />

</LinearLayout>

Modifiez le fichier activity_rssfeed.xml existant. Ce fichier est la mise en page par défaut pour l'activité RssfeedActivity et elle affiche les deux fragments.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <fragment
        android:id="@+id/listFragment"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:attr/actionBarSize"
        class="com.example.android.rssfeed.MyListFragment" ></fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="match_parent"
        class="com.example.android.rssfeed.DetailFragment" >
        <!-- Preview: layout=@layout/details -->
    </fragment>

</LinearLayout>

10-4. Création des classes Fragment

Maintenant, il faut créer les classes Fragment. Commençons par la classe DetailFragment.

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class DetailFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rssitem_detail,
        container, false);
    return view;
  }

  public void setText(String item) {
    TextView view = (TextView) getView().findViewById(R.id.detailsText);
    view.setText(item);
  }
}

Créons la classe MyListFragment. Malgré son nom, elle ne va pas afficher une liste, elle aura juste un bouton permettant d'envoyer la date courante au fragment détaillé.

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class MyListFragment extends Fragment {
  
  private OnItemSelectedListener listener;
  
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_rsslist_overview,
        container, false);
    Button button = (Button) view.findViewById(R.id.button1);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        updateDetail();
      }
    });
    return view;
  }

  public interface OnItemSelectedListener {
      public void onRssItemSelected(String link);
    }
  
  @Override
    public void onAttach(Activity activity) {
      super.onAttach(activity);
      if (activity instanceof OnItemSelectedListener) {
        listener = (OnItemSelectedListener) activity;
      } else {
        throw new ClassCastException(activity.toString()
            + " must implemenet MyListFragment.OnItemSelectedListener");
      }
    }
  
  
  // May also be triggered from the Activity
  public void updateDetail() {
    // create fake data
    String newTime = String.valueOf(System.currentTimeMillis());
    // Send data to Activity
    listener.onRssItemSelected(newTime);
  }
}

10-5. L'activité RssfeedActivity

Modifiez la classe RssfeedActivity avec le code suivant :

 
Sélectionnez
package com.example.android.rssfeed;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rssfeed);
    }

    // if the wizard generated an onCreateOptionsMenu you can delete
    // it, not needed for this tutorial

  @Override
  public void onRssItemSelected(String link) {
    DetailFragment fragment = (DetailFragment) getFragmentManager()
            .findFragmentById(R.id.detailFragment);
        if (fragment != null && fragment.isInLayout()) {
          fragment.setText(link);
        } 
  }
    
}

10-6. Exécution

Exécutez votre exemple. Les deux fragments devraient être affichés en mode portrait et paysage. Si vous appuyez sur le bouton dans le fragment ListFragment, le fragment DetailFragment devrait être mis à jour.

11. Exercice avec les fragments, utilisation du mode portrait

11-1. Création des mises en page pour le mode portrait

L'activité RssfeedActivity doit utiliser un fichier de mise en page particulier en mode portrait. En mode portrait, Android va vérifier le répertoire layout-port pour les fichiers correspondants. Si Android ne trouve pas de fichier correspondant, il utilise le répertoire layout.

Pour cela, il faut créer un répertoire res/layout-port. Après cela, créez le fichier de mise en page activity_rssfeed.xml dans le répertoire res/layout-port.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <fragment
        android:id="@+id/listFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:attr/actionBarSize"
        class="com.example.android.rssfeed.MyListFragment" />
</LinearLayout>

Créez aussi le fichier de mise en page activity_detail.xml. Cette mise en page sera utilisée par l'activité DetailActivity. Notez que l'on aurait aussi pu le créer dans le répertoire res/layout mais il n'est utilisé qu'en mode portrait c'est pourquoi nous le plaçons dans ce répertoire.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <fragment
        android:id="@+id/detailFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.example.android.rssfeed.DetailFragment" />

</LinearLayout>

11-2. L'activité DetailActivity

Créez une nouvelle activité nommée DetailActivity avec le code suivant :

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.TextView;

public class DetailActivity extends Activity {
  
  public static final String EXTRA_URL = "url";
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Need to check if Activity has been switched to landscape mode
    // If yes, finished and go back to the start Activity
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
      finish();
      return;
    }
    setContentView(R.layout.activity_detail);
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      String s = extras.getString(EXTRA_URL);
      TextView view = (TextView) findViewById(R.id.detailsText);
      view.setText(s);
    }
  }
}

Assurez-vous aussi d'enregistrer cette activité dans le fichier AndroidManifest.xml.

11-3. Modification de l'activité RssfeedActivity

Modifiez l'activité RssfeedActivity pour afficher l'activité DetailActivity au cas où l'autre fragment n'est pas présent dans la mise en page.

 
Sélectionnez
package com.example.android.rssfeed;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;

public class RssfeedActivity extends Activity implements
    MyListFragment.OnItemSelectedListener {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rssfeed);
  }

  @Override
  public void onRssItemSelected(String link) {
    DetailFragment fragment = (DetailFragment) getFragmentManager()
        .findFragmentById(R.id.detailFragment);
    if (fragment != null && fragment.isInLayout()) {
      fragment.setText(link);
    } else {
      Intent intent = new Intent(getApplicationContext(),
          DetailActivity.class);
      intent.putExtra(DetailActivity.EXTRA_URL, link);
      startActivity(intent);

    }
  }

}

11-4. Exécution

Lancez votre exemple. Si vous lancez votre application en mode portrait, vous ne devriez voir qu'un seul fragment. Utilisez le raccourci Ctrl+F11 pour changer l'orientation. En mode paysage, vous devriez voir les deux fragments. Si vous appuyez sur le bouton en mode portrait, une nouvelle activité DetailActivity est démarrée et montre la date courante. En mode paysage, vous voyez les deux fragments.

Image non disponible

12. Exercice avec les fragments dynamiques

12-1. But

Modifiez l'exemple RssReader de manière à ce que des fragments dynamiques soient utilisés.

Une mise en page à plusieurs panneaux doit être utilisée dans le cas des écrans larges, par exemple pour les tablettes. Le point de basculement doit être de 600dpi.

Implémentez la solution avec une activité et plusieurs fragments, supprimez l'activité DetailsActivity à la fin de cet exercice.

12-2. Utilisation d'un espace réservé pour les fragments

Remplacez le fragment statique dans le répertoire avec un FrameLayout comme espace réservé.

12-3. Utilisation du gestionnaire de fragments pour remplacer un fragment

Implémentez une solution de manière à ce que vous n'ayez qu'une seule activité et remplacez les fragments à la demande.

13. Liens et littérature

14. Remerciements

Vous pouvez retrouver l'article original ici : Using Fragments in Android - Tutorial. Nous remercions Lars Vogel qui nous a aimablement autorisés à traduire et héberger ses articles.

Nos remerciements à Phillipe DUVAL pour sa relecture orthographique.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Lars Vogel et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.