Dilemme: quand utiliser Fragments vs Activités:

786

Je sais qu'ils Activitiessont conçus pour représenter un seul écran de mon application, alors qu'ils Fragmentssont conçus pour être des mises en page d'interface utilisateur réutilisables avec une logique intégrée à l'intérieur.

Jusqu'à il n'y a pas longtemps, j'ai développé une application qui disait qu'il fallait les développer. J'ai créé un Activitypour représenter un écran de mon application et utilisé des fragments pour ViewPagerou Google Maps. J'ai rarement créé une ListFragmentou une autre interface utilisateur qui peut être réutilisée plusieurs fois.

Récemment, je suis tombé sur un projet qui ne contient que 2 l' Activitiesun est un SettingsActivityet l'autre est le MainActivity. La disposition du MainActivityest remplie de nombreux fragments d'interface utilisateur en plein écran cachés et un seul est affiché. Dans la Activitylogique il y en a beaucoup FragmentTransitionsentre les différents écrans de l'application.

Ce que j'ai aimé dans cette approche, c'est que parce que l'application utilise un ActionBar, elle reste intacte et ne bouge pas avec l'animation de changement d'écran, ce qui se produit avec le Activitychangement. Cela donne une sensation plus fluide à ces transitions d'écran.

Donc je suppose que ce que je demande, c'est de partager votre manière de développement actuelle sur ce sujet, je sais que cela pourrait ressembler à une question d'opinion à première vue, mais je la vois comme une question de conception et d'architecture Android ... Pas vraiment un basé sur une opinion.

MISE À JOUR (01.05.2014): Suite à cette présentation par Eric Burke de Square , (ce que je dois dire est une excellente présentation avec beaucoup d'outils utiles pour les développeurs Android. Et je n'ai aucun lien avec Square)

http://www.infoq.com/presentations/Android-Design/

D'après mon expérience personnelle au cours des derniers mois, j'ai trouvé que la meilleure façon de construire mes applications est de créer des groupes de fragments qui viennent représenter un flux dans l'application et présenter tous ces fragments en un Activity. Donc, fondamentalement, vous aurez le même nombre de Activitiesdans votre application que le nombre de flux. De cette façon, la barre d'action reste intacte sur tous les écrans du flux, mais est recréée en modifiant un flux, ce qui a beaucoup de sens. Comme le déclare Eric Burke et comme je l'ai compris, la philosophie d'utiliser le moins Activitiespossible n'est pas applicable à toutes les situations car elle crée un gâchis dans ce qu'il appelle l'activité «Dieu».

Emil Adz
la source

Réponses:

271

Les experts vous diront: "Quand je verrai l'interface utilisateur, je saurai s'il faut utiliser un Activityou un Fragment". Au début, cela n'aura aucun sens, mais avec le temps, vous pourrez réellement dire si vous en avez besoin Fragmentou non.

Il y a une bonne pratique que j'ai trouvée très utile pour moi. Cela m'est venu à l'esprit alors que j'essayais d'expliquer quelque chose à ma fille.

À savoir, imaginez une boîte qui représente un écran. Pouvez-vous charger un autre écran dans cette boîte? Si vous utilisez une nouvelle boîte, devrez-vous copier plusieurs éléments de la première boîte? Si la réponse est Oui, vous devez utiliser Fragments, car la racine Activitypeut contenir tous les éléments dupliqués pour vous faire gagner du temps dans leur création, et vous pouvez simplement remplacer des parties de la boîte.

Mais n'oubliez pas que vous avez toujours besoin d'un conteneur ( Activity) ou vos pièces seront dispersées. Donc, une boîte avec des pièces à l'intérieur.

Prenez soin de ne pas abuser de la boîte. Les experts Android UX conseillent (vous pouvez les trouver sur YouTube) quand nous devrions explicitement en charger un autre Activity, au lieu d'utiliser un Fragment(comme lorsque nous traitons le tiroir de navigation qui a des catégories). Une fois que vous vous sentez à l'aise avec Fragments, vous pouvez regarder toutes leurs vidéos. Plus encore, ils sont obligatoires.

Pouvez-vous dès maintenant regarder votre interface utilisateur et déterminer si vous avez besoin d'un Activityou d'un Fragment? Avez-vous eu une nouvelle perspective? Je pense que oui.

sandalone
la source
4
avez-vous un lien vers le fil youtube que vous avez mentionné? Je recherche «experts Android UX» et «Android UX», mais je ne sais pas exactement de quelles vidéos vous parlez.
moi--
2
Plus maintenant, je l'ai regardé il y a plus d'un an. Recherche d'un développeur Android parlant d'UX
sandalone
1
Un exemple de considération: l'activité a parentActivity afin que nous puissions synthétiser le backstack tout en entrant à partir de la notification, mais je ne pense pas qu'il y ait un tel parentFragment.
fikr4n
@BornToCode il y a getParentFragment: developer.android.com/reference/android/support/v4/app/…
ToolmakerSteve
@ToolmakerSteve oui c'est getParentFragment, mais ce n'est pas ce que je voulais dire mec, voir developer.android.com/guide/topics/manifest/…
fikr4n
129

Ma philosophie est la suivante:

Créez une activité uniquement si elle est absolument indispensable. Avec la pile arrière rendue disponible pour valider un tas de transactions de fragments, j'essaie de créer le moins d'activités possible dans mon application. En outre, la communication entre divers fragments est beaucoup plus facile que l'envoi de données entre les activités.

Les transitions d'activité coûtent cher, non? Du moins, je le crois - puisque l'ancienne activité doit être détruite / suspendue / arrêtée, poussée sur la pile, puis la nouvelle activité doit être créée / démarrée / reprise.

C'est juste ma philosophie depuis l'introduction des fragments.

VJ Vélan Solutions
la source
2
vrai, mais comme vous l'avez écrit, il est parfois nécessaire d'utiliser des activités. un exemple est un écran d'appareil photo, où il est préférable de l'utiliser en mode paysage. un autre exemple est l'écran de configuration qui s'affiche lorsque vous placez un appWidget personnalisé (sur le "bureau" - l'application de lancement).
développeur Android
Merci d'avoir répondu et d'avoir partagé votre expérience. Vous pensez donc que c'est une bonne pratique dans Android de limiter l'application à une seule activité et d'utiliser Fragment pour tous les écrans si l'architecture de l'application le permet?
Emil Adz
1
Alors, comment résolvez-vous le problème des fragments qui doivent passer l'autre "état"? Tous les états de tous vos fragments doivent vivre dans la même activité, sinon vous êtes obligé d'utiliser un singleton.
Mr_E
36
Je ne suis pas convaincu que la communication entre divers fragments soit beaucoup plus facile que d'envoyer des données entre les activités.
Denny
3
Au moins, onActivityResult()est plus sûr et plus facile que les rappels de fragments.
CoolMind
59

Eh bien, selon les conférences de Google (peut-être ici , je ne me souviens pas), vous devriez envisager d'utiliser des fragments chaque fois que cela est possible, car cela rend votre code plus facile à maintenir et à contrôler.

Cependant, je pense que dans certains cas, cela peut devenir trop complexe, car l'activité qui héberge les fragments doit naviguer / communiquer entre eux.

Je pense que vous devriez décider par vous-même de ce qui vous convient le mieux. Il n'est généralement pas si difficile de convertir une activité en un fragment et vice versa.

J'ai créé un article sur ce dillema ici , si vous souhaitez en lire plus.

développeur android
la source
5
Merci d'avoir répondu et d'avoir partagé votre expérience. Vous pensez donc que c'est une bonne pratique dans Android de limiter l'application à une seule activité et d'utiliser Fragment pour tous les écrans si l'architecture de l'application le permet?
Emil Adz
Cela dépend du projet, mais si cela vous devient trop compliqué, vous pouvez également vous séparer de plusieurs activités. N'ayez pas peur d'utiliser l'une des méthodes. Vous pouvez également les utiliser tous les deux. Parfois, il serait peut-être trop difficile pour vous d'utiliser des fragments au lieu d'activités. Je pense que vous devriez essayer d'utiliser des fragments, mais ne le forcez pas à être partout si cela vous gêne trop ...
développeur Android
que se passe-t-il si je veux conserver cet effet de l'ActionBar restant intact et que tout le contenu est changé? Est-il possible d'y parvenir avec des activités?
Emil Adz
27

Pourquoi je préfère le fragment à l'activité dans TOUS LES CAS.

  • L'activité coûte cher. Dans Fragment, les vues et les états de propriété sont séparés - chaque fois qu'un fragment se trouve backstack, ses vues sont détruites. Vous pouvez donc empiler beaucoup plus de fragments que d'activité.

  • Backstackmanipulation. Avec FragmentManager, il est facile d'effacer tous les fragments, d'en insérer plus que sur les fragments et les etc. Mais pour Activity, ce sera un cauchemar de manipuler ces trucs.

  • Un cycle de vie bien prévisible . Tant que l'activité hôte n'est pas recyclée. les fragments du sac à dos ne seront pas recyclés. Il est donc possible d'utiliser FragmentManager::getFragments()pour trouver un fragment spécifique (non recommandé).

Qylin
la source
HI, j'ai lu votre avis sur les avantages de Frag par rapport à Act, avez-vous un projet pour montrer la même chose dans votre Github Repo?
Ümañg ßürmån
24

Depuis Jetpack , l' application à activité unique est l'architecture préférée. Utile en particulier avec le composant Architecture de navigation .

la source

Francis
la source
Merci pour ça!
Simão Garcia
1
J'ai lu sur Jetpack pour la première fois aujourd'hui. :) Nous créons des applications à activité unique depuis l'introduction des fragments. La multi-activité est beaucoup plus compliquée.
L'incroyable
1
@TheincredibleJan Vous avez raison, l'architecture Single Activity App était une meilleure solution bien avant Jetpack
Francis
12

À mon avis, ce n'est pas vraiment pertinent. Le facteur clé à considérer est

  1. à quelle fréquence allez-vous réutiliser des parties de l'interface utilisateur (menus par exemple),
  2. l'application est-elle également pour les tablettes?

L'utilisation principale des fragments est de créer des activités à volets multiples, ce qui le rend parfait pour les applications réactives pour tablette / téléphone.

Isaac Urbina
la source
Je dirais que l'utilisation principale des fragments est de créer des vues personnalisées sans les considérer comme des vues personnalisées. c'est ce qui arrive de toute façon. Les fragments que Google nous a initialement présentés comme un moyen pratique de créer des applications réactives pour tablette, vous pouvez donc les coller dans différentes activités si vous le souhaitez. un moyen d'attacher du code à une vue, plus ou moins, et de les coller où vous le souhaitez (sans créer des vues personnalisées).
Lassi Kinnunen
11

N'oubliez pas qu'une activité est un bloc / composant d'application qui peut être partagé et démarré via Intent! Ainsi, chaque activité de votre application ne devrait résoudre qu'un seul type de tâche. Si vous n'avez qu'une seule tâche dans votre application, je pense que vous n'avez besoin que d'une seule activité et de plusieurs fragments si nécessaire. Bien sûr, vous pouvez réutiliser des fragments dans des activités futures qui résolvent une autre tâche. Cette approche sera une séparation claire et logique des tâches. Et vous n'avez pas besoin de maintenir une activité avec des paramètres de filtre d'intention différents pour différents ensembles de fragments. Vous définissez les tâches au stade de la conception du processus de développement en fonction des besoins.

client
la source
Dans nos applications, le seul type de tâche de l'activité est de tenir le tiroir de navigation pour entrer les différents fragments. :) Pourquoi devrais-je me débattre avec des intentions pour des fragments? Il est clair et logique de conserver une référence statique à une classe de données "globale" pour les données globales et de transmettre certaines valeurs à une méthode de création d'instance d'un fragment.
L'incroyable
9

Il y a plus que vous ne le réalisez, vous devez vous rappeler qu'une activité qui est lancée ne détruit pas implicitement l'activité appelante. Bien sûr, vous pouvez le configurer de telle sorte que votre utilisateur clique sur un bouton pour accéder à une page, vous démarrez l'activité de cette page et détruisez celle en cours. Cela entraîne beaucoup de frais généraux. Le meilleur guide que je puisse vous donner est:

** Commencez une nouvelle activité uniquement s'il est logique d'avoir l'activité principale et celle-ci ouverte en même temps (pensez à plusieurs fenêtres).

Google Drive est un excellent exemple de cas où il est logique d'avoir plusieurs activités. L'activité principale fournit un explorateur de fichiers. Lorsqu'un fichier est ouvert, une nouvelle activité est lancée pour afficher ce fichier. Vous pouvez appuyer sur le bouton des applications récentes qui vous permettra de revenir au navigateur sans fermer le document ouvert, puis peut-être même d'ouvrir un autre document en parallèle au premier.

TheHebrewHammer
la source
Re "Démarrer une nouvelle activité uniquement s'il est logique que l'activité principale et celle-ci soient ouvertes en même temps (pensez à plusieurs fenêtres)." Je ne pense pas. Cette situation est bien résolue en utilisant des fragments attach / detachméthodes.
ToolmakerSteve
7

Chose que j'ai faite: Utiliser moins de fragments lorsque cela est possible. Malheureusement, c'est possible dans presque tous les cas. Donc, je me retrouve avec beaucoup de fragments et un peu d'activités. Quelques inconvénients que j'ai réalisé:

  • ActionBar& Menu: Lorsque 2 fragments ont un titre, un menu différent, cela
    sera difficile à gérer. Ex: lors de l'ajout d'un nouveau fragment, vous pouvez modifier le titre de la barre d'action, mais lorsque vous le faites apparaître, il backstackn'y a aucun moyen de restaurer l'ancien titre. Vous pouvez avoir besoin d'une barre d'outils dans chaque fragment pour ce cas, mais croyez-moi, cela vous passera plus de temps.
  • Lorsque nous en avons besoin startForResult, l'activité n'a pas de fragment.
  • Ne pas avoir d'animation de transition par défaut

Ma solution consiste à utiliser une activité pour envelopper un fragment à l'intérieur. Nous avons donc une barre d'action séparée, un menu startActivityForResult, une animation, ...

J'aime coder
la source
1
Points très utiles, merci. Pouvez-vous clarifier " une activité pour envelopper un fragment "? Avez-vous créé une activité distincte pour chaque fragment? Si oui, avez-vous besoin de Fragment?
ToolmakerSteve
3
il y a un moyen de restaurer le titre et les trucs. utiliser getSupportFragmentManager().addOnBackStackChangedListenerpour ajouter un écouteur. obtenir le fragment actuel dans cet écouteur, puis définir le titre et les éléments.
babay
4

Le gros avantage d'une fragmentsuractivité est que le code utilisé pour le fragment peut être utilisé pour différentes activités, donc il permet la réutilisation du code dans le développement d'applications.

Sanchit Bhasin
la source
3
Comment? Peux-tu donner un exemple, s'il te plaît?
sofs1
1
@ sofs1 Votre question n'a pas beaucoup de sens. Tout code dans un fragment reste le même quelle que soit l'activité à partir de laquelle le fragment est instancié.
L'incroyable
@TheincredibleJan Mais ne pourrions-nous pas également dire "Tout code dans une activité reste le même, quelle que soit l'activité à partir de laquelle la deuxième activité est instanciée."? Je ne vois pas la différence.
iforce2d
3

utiliser une activité par application pour fournir une base à fragment utiliser fragmentpour l'écran, fragmentssont légers par rapport aux activites fragments sont des fragments réutilisables sont mieux adaptés pour une application qui prend en charge à la fois le téléphone et la tablette

varg
la source
2

Vous êtes libre d'en utiliser un.
Fondamentalement, vous devez évaluer la meilleure solution pour votre application. Réfléchissez à la façon dont vous gérerez le flux commercial et à la façon de stocker / gérer les préférences de données.

Pensez à la façon dont les fragments stockent les données de déchets. Lorsque vous implémentez le fragment, vous avez une racine d'activité à remplir avec des fragments. Donc, si vous essayez d'implémenter beaucoup d'activités avec trop de fragments, vous devez considérer les performances de votre application, car vous manipulez (parle grossièrement) le cycle de vie de deux contextes, souvenez-vous de la complexité.

Rappelez-vous: dois-je utiliser des fragments? Pourquoi pas?

Cordialement.

Franklin Hirata
la source
1

J'utilise des fragments pour une meilleure expérience utilisateur. Par exemple, si vous avez un bouton et que vous souhaitez exécuter, disons un service Web lorsque vous cliquez dessus, j'attache un fragment à l'activité parente.

if (id == R.id.forecast) {

    ForecastFragment forecastFragment = new ForecastFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.main_content, forecastFragment);
    ft.addToBackStack("backstack");
    forecastFragment.setArguments(b);
    ft.commit();
}

De cette façon, l'utilisateur n'aura pas à se déplacer dans une autre activité.

Et deuxièmement, je préfère les fragments parce que vous pouvez les manipuler facilement pendant la rotation.

Théo
la source
Qu'est-ce qui fait de cet exemple une meilleure expérience utilisateur? Comment sauront-ils (ou prendront-ils soin) qu'ils font une activité ou un fragment?
iforce2d
1

Cela dépend vraiment de ce que vous voulez construire. Par exemple, navigation drawerutilise des fragments. Les onglets sont également utilisés fragments. Une autre bonne implémentation est celle où vous avez listview. Lorsque vous faites pivoter le téléphone et cliquez sur une ligne, l'activité est affichée dans la moitié restante de l'écran. Personnellement, j'utilise fragmentset fragment dialogs, comme c'est plus professionnel. De plus, ils sont manipulés plus facilement en rotation.

Théo
la source