Conception d'interface utilisateur Android Travailler avec des fragments

La nouvelle API Fragment pour Android, introduite dans Android 3.0, facilite les interfaces utilisateur dynamiques. Dans ce tutoriel, découvrez comment convertir un flux de travail ListView en WebView à deux écrans en un flux de travail à un seul écran conçu pour les grands écrans, tels que ceux trouvés sur les tablettes..

Changements ultérieurs dans Techniques et logiciels

Certains aspects des applications ou techniques utilisées dans ce tutoriel ont changé depuis sa publication initiale. Cela pourrait le rendre un peu difficile à suivre. Nous vous recommandons de consulter ces didacticiels plus récents sur le même sujet:

  • SDK Android: utilisation de fragments

Le rythme de ce tutoriel sera plus rapide que certains de nos tutoriels pour débutants; vous devrez peut-être consulter certains des autres didacticiels Android sur ce site ou même dans la référence du SDK d'Android si vous n'êtes pas familiarisé avec l'un des concepts de base d'Android et des classes abordés dans ce didacticiel. Le dernier exemple de code qui accompagne ce didacticiel est disponible au téléchargement en open-source à partir de l'hébergement de code Google..

Présentation des fragments

Avant de commencer, définissons ce qu'est un fragment, à un niveau élevé. Un fragment est généralement un bloc d'interface utilisateur avec son propre cycle de vie. Si cela ressemble beaucoup à une activité, c'est parce que est un peu comme une activité. Cependant, un fragment est différent d'une activité, en ce sens qu'un fragment doit exister dans une activité. Un fragment ne doit pas nécessairement être associé à la même activité à chaque instanciation, ce qui lui confère une certaine souplesse. Également comme une activité, un fragment n'a besoin d'aucune interface utilisateur.

Étape 0: Mise en route

Ce tutoriel suppose que vous commencerez là où notre tutoriel ListView s'est arrêté. Vous pouvez télécharger ce code et le compiler à partir de là, même si certaines tâches vous seront confiées sans aide, ou vous pouvez télécharger le code de ce didacticiel et le suivre..

Étape 1: Reconcevoir les écrans

La figure suivante illustre le flux de travail existant de notre application de lecture d'articles Mobiletuts + (le tutoriel ListView) avant la conception et la mise en œuvre d'une conception de Fragment:

Ce flux de travail fonctionne correctement sur un écran de téléphone relativement petit. Cependant, sur un grand écran, comme l'écran 10 "du Motorola Xoom, il y a beaucoup d'espace perdu sur l'écran ListView. L'écran WebView a l'air bien, bien qu'un peu ennuyeux.

C'est ici que les fragments entrent en jeu: sur des écrans plus grands, nous pourrions fournir une interface utilisateur plus efficace si nous pouvions afficher ListView sur le même écran que WebView. Lorsque l'utilisateur clique sur un élément ListView spécifique dans le volet? De gauche?, WebView sur le côté droit se met à jour pour afficher le contenu approprié. Ce type de flux de travail est fréquemment utilisé dans les lecteurs de courrier électronique ou de flux de documents. La figure suivante illustre une telle refonte:

Étape 2: Conversion en une conception basée sur des fragments

Maintenant que nous savons comment le nouveau flux de travail de l'écran sera conçu, nous savons également que les deux activités en cours devront être converties en fragments. Nous ferons la conversion en plusieurs étapes. La première étape consiste à laisser les écrans inchangés visuellement, mais à modifier chaque écran pour utiliser un fragment. Un fragment contiendra le ListView actuel et un autre contiendra le WebView. Nous passerons ensuite à une implémentation à un seul écran, qui implique de modifier la messagerie entre les activités transformées en ListView et WebView..

Cependant, commencez par modifier la cible de génération de projet de votre application sur Android 3.0. Pour ce faire depuis Eclipse, cliquez avec le bouton droit sur le projet et choisissez Propriétés. Accédez à la section Android et cochez la case en regard d'Android 3.0. Nous n'utilisons aucune API Google. La version du projet Android Open Source est suffisante. Puis cliquez sur le bouton OK.

Maintenant, vous aurez accès aux nouvelles API, y compris l'API Fragments.

Remarque: dans un prochain tutoriel, nous parlerons de l'utilisation de la nouvelle couche de compatibilité pour permettre aux technologies telles que l'API Fragment de fonctionner sur les versions antérieures d'Android. Pour l'instant, cependant, ils auront besoin d'un appareil avec Android 3.0, Honeycomb.

Étape 3: Création des classes de fragments

Créez deux nouvelles classes Java pour représenter les deux fragments: les écrans ListView et WebView. Nommez-les TutListFragment et TutViewerFragment. TutListFragment étend la classe ListFragment et TutViewerFragment ne fait qu’étendre la classe Fragment.

Dans la classe TutListFragment, nous devons redéfinir deux méthodes: onListItemClick () et onCreate (). Le contenu de ces méthodes devrait sembler familier; ils correspondent à ce que nous avions précédemment dans la classe TutListActivity. Cela changera bientôt, mais pas encore. Voici une liste de la classe TutListFragment, pour le moment:

 @Override public void onListItemClick (ListerVue, Voir v, int, id long) String [] links = getResources (). GetStringArray (R.array.tut_links); Contenu de la chaîne = liens [position]; Intention showContent = new Intent (getActivity (). GetApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (contenu)); startActivity (showContent);  @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setListAdapter (ArrayAdapter.createFromResource (getActivity () .getApplicationContext (), R.array.tut_titles, R.layout.list_item)); 

La classe TutViewerFragment est un peu plus simple. Nous utilisons le fait que nous savons (pour le moment) que le fragment s'exécute sous la même activité que précédemment et récupérons les données d'intention directement à partir de la classe Fragment. Ajoutez une méthode de substitution pour la méthode onCreateView (). Cette méthode devrait maintenant ressembler à ceci:

 @Override public View onCreateView (inflateur LayoutInflater, conteneur ViewGroup, Bundle savedInstanceState) Intention launchingIntent = getActivity (). GetIntent (); String content = launchingIntent.getData (). ToString (); Visionneuse WebView = (WebView) inflater.inflate (R.layout.tut_view, conteneur, false); viewer.loadUrl (contenu); visionneuse de retour; 

La possibilité d'accéder directement à l'instance d'activité est utile, mais créera un problème ultérieurement. Que se passe-t-il si ce fragment est à l'écran avec le fragment de liste? Dans ce scénario, il n'y aura pas d'intention de lancement pour obtenir l'URL. De même, dans TutListFragment, nous lançons une nouvelle activité directement chaque fois que l'utilisateur clique sur un élément de la liste. Et si le TutViewFragment existait dans la même activité? Si tel est le cas, le lancement d'une nouvelle activité n'aurait aucun sens. Nous reviendrons pour résoudre ces problèmes plus tard dans ce tutoriel..

Étape 4: Ajout des ressources de mise en page de fragment

Créez maintenant un nouveau fichier de présentation appelé tutlist_fragment.xml pour représenter le fragment contenant la liste des articles. Une ressource de mise en page Fragment utilise la balise et référence la classe Fragment que vous avez créée..

   

Créez ensuite un fichier de présentation similaire appelé tutview_fragment.xml:

   

Étape 5: Mise à jour des classes d'activité

Les classes TutListActivity et TutViewerActivity doivent maintenant être mises à jour. La classe TutListActivity a une seule méthode, onCreate (), qui devrait maintenant être mise à jour pour charger la ressource de mise en page Fragment appropriée que vous avez créée à l'étape précédente, comme ceci:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutlist_fragment); 

De plus, notez que TutListActivity doit hériter de la classe Activity et non de ListActivity..

La classe TutViewerActivity requiert une modification similaire. Sa méthode onCreate () devrait maintenant ressembler à ceci:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment); 

Étape 6: Vérification de vos progrès

Essayez de lancer l'application maintenant. Vous noterez qu'il fait exactement ce qu'il faisait auparavant. Pas très excitant encore, n'est-ce pas? Cependant, toute l'interface utilisateur est maintenant exécutée à l'aide de fragments. Cela permettra aux prochaines modifications que vous devez apporter de se dérouler sans à-coup, car nous ajoutons une nouvelle disposition pour combiner les deux fragments pour des affichages plus grands à montrer à l'utilisateur sur un seul écran. Cependant, comme vous l'avez peut-être remarqué, la communication entre les fragments est gérée de manière identique à la façon dont nous communiquons entre les activités. En fait, nous avons utilisé la connaissance selon laquelle l'activité à laquelle chaque fragment était associé restait inchangée. Ce ne sera pas le cas si nous avons une seule activité qui contient et gère les deux fragments. Réparons cela en premier.

Étape 7: Modification de la communication pour TutListFragment

Comme vous l'avez appris à l'étape 3, le lancement d'une activité directement à partir de l'objet TutListFragment n'a plus de sens. L’interface utilisateur WebView peut, en fait, faire partie de la même activité que la liste - c’est notre plan pour les écrans plus grands. Dans ce cas, nous souhaitons simplement mettre à jour l'URL de WebView dans le deuxième fragment..

Pour faire ce changement, nous devons faire plusieurs choses. Premièrement, créons des fragments indépendants de l’activité dans laquelle ils résident. Pour ce faire, ajoutez une interface d'écoute à la classe TutListFragment, en tant que telle:

 interface publique OnTutSelectedListener public void onTutSelected (Uri tutUri); 

Et déclenchez-le en mettant à jour la méthode onListItemClickListener () comme suit:

 @Override public void onListItemClick (ListerVue, Voir v, int, id long) String [] links = getResources (). GetStringArray (R.array.tut_links); Contenu de la chaîne = liens [position]; tutSelectedListener.onTutSelected (Uri.parse (contenu)); 

Ensuite, demandez à la classe TutListActivity d'implémenter l'interface OnTutSelectedListener, comme suit:

 TutListFragment.OnTutSelectedListener ? @Override public void onTutSelected (Uri tutUri) Intention showContent = new Intent (getApplicationContext (), TutViewerActivity.class); showContent.setData (tutUri); startActivity (showContent); 

Nous avons donc maintenant les fonctionnalités réparties entre le fragment, qui gère les actions de l'interface utilisateur, et l'activité, qui peut être un contrôleur, transmettant les données à l'activité suivante. Nous modifierons la méthode onTutSelected () ultérieurement pour décider de lancer ou non une nouvelle instance Activity ou de mettre à jour l'instance de fragment existante..

Étape 8: Modification de la communication pour TutViewerFragment

Passons maintenant à la classe TutViewerFragment, qui doit également être mise à jour. Au lieu d'interroger l'intention de lancement pour savoir quelle URL charger, le fragment attendra de savoir quelle URL charger. De cette manière, nous pouvons mettre à jour WebView directement et ne pas recréer le fragment à chaque chargement..

Commencez par modifier la classe TutViewerFragment afin qu'elle contienne une nouvelle méthode appelée updateUrl ():

 public void updateUrl (String newUrl) if (viewer! = null) viewer.loadUrl (newUrl); 

Ensuite, supprimez toutes les fonctionnalités de la méthode onCreateView (), à l'exception de l'appel inflate (). Dans la classe TutViewerActivity, ajoutez la fonctionnalité pour récupérer l’intention, puis appelez la méthode updateUrl (), comme suit:

 @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.tutview_fragment); Intention launchingIntent = getIntent (); String content = launchingIntent.getData (). ToString (); TutViewerFragment viewer = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); viewer.updateUrl (contenu); 

À ce stade, le comportement de l'application reste inchangé. Les fragments, cependant, peuvent maintenant exister au sein de la même activité ou en être séparés sans autre changement de code.

Étape 9: Ajout d'une disposition de double fragment

Créons maintenant une mise en page avec les deux fragments, à utiliser dans certaines situations. Dans le dossier layout-land (que vous devrez peut-être créer), ajoutez une copie de tutlist_fragment.xml. Cela fournira une mise en page différente pour l'orientation paysage sur n'importe quel écran paysage. Le mode Portrait restera inchangé. Editez le fichier pour qu'il ressemble à la disposition suivante avec les deux fragments:

       

Cela divisera l'écran horizontalement entre les deux fragments.

Étape 10: Ajout d'un choix dynamique

Nous pouvons maintenant ajouter une logique simple à l'application pour choisir entre le lancement d'une nouvelle activité (le flux de travail à deux écrans) et la mise à jour d'un fragment existant (le flux de travail à un écran)..

Pour ce faire, mettez à jour la méthode onTutSelected () de la classe TutListActivity comme suit:

 @Override public void onTutSelected (String tutUrl) TutViewerFragment viewer = (TutViewerFragment) getFragmentManager () .findFragmentById (R.id.tutview_fragment); if (spectateur == null ||! viewer.isInLayout ()) Intention showContent = new Intent (getApplicationContext (), TutViewerActivity.class); showContent.setData (Uri.parse (tutUrl)); startActivity (showContent);  else viewer.updateUrl (tutUrl); 

Tout ceci consiste à récupérer le fragment et à vérifier s'il fait partie de la présentation existante de l'activité. Sinon, l'activité du visualiseur est lancée, sinon le fragment existant est mis à jour à la place..

Étape 11: Exécution de la nouvelle application prenant en compte Fragment

À ce stade, l'application fonctionnera désormais dans deux modes différents: portrait est inchangé, tandis que paysage affiche ListView à gauche de WebView. Il existe plusieurs améliorations qui pourraient être apportées à ce stade, mais elles concernent les variantes d’ajustements, d’optimisation et de pick-pick et principalement pour le polissage. Par exemple, si vous êtes en mode WebView en mode portrait et que vous faites pivoter l'écran, le résultat reste simplement l'écran WebView. Vous devez appuyer en arrière pour accéder à la vue double. Le polissage n’entre pas dans le cadre de ce didacticiel, mais vous pouvez voir comment, avec l’utilisation judicieuse des dispositions et un peu de logique d’activité, vous pouvez obtenir des flux de travail puissants mais flexibles pour une variété d’écrans et de périphériques..

Conclusion

L'API Fragment permet d'organiser les composants de l'interface utilisateur de manière à pouvoir les réutiliser lors d'activités De cette manière, une application peut ajuster dynamiquement son flux de travail et ses interfaces utilisateur avec un temps système relativement faible en codage. Vous avez également constaté qu’une application reposant sur des fragments est plus facile à réorganiser. Mieux encore, à peu près toutes les applications peuvent exploiter des fragments maintenant qu'ils sont disponibles via une bibliothèque de compatibilité fournie par Google et compatible dès Android 1.6..
Maintenant, sortez et fragmentez l'interface utilisateur de vos applications et créez des interfaces utilisateur géniales pour toutes les tailles et formes d'écran.!

à propos des auteurs

Les développeurs mobiles Lauren Darcey et Shane Conder ont co-écrit plusieurs livres sur le développement Android: un livre de programmation en profondeur intitulé Développement d'applications sans fil Android et Sams Teach Yourself Développement d'applications Android en 24 heures. Lorsqu'ils n'écrivent pas, ils passent leur temps à développer des logiciels mobiles dans leur entreprise et à fournir des services de conseil. Vous pouvez les contacter par courrier électronique à l'adresse [email protected], via leur blog à l'adresse androidbook.blogspot.com et sur Twitter @androidwireless..

Besoin d'aide pour écrire des applications Android? Consultez nos derniers livres et ressources!

я я