Quel est l'avantage d'utiliser des fragments dans Android plutôt que des vues?

102

Lors du développement pour Android, vous pouvez définir votre SDK cible (ou minimum) sur 4 (API 1.6) et ajouter le package de compatibilité Android (v4) pour ajouter la prise en charge de Fragments. Hier, j'ai fait cela et mis Fragmentsen œuvre avec succès pour visualiser les données d'une classe personnalisée.

Ma question est la suivante: quel est l'avantage d'utiliser Fragmentspar opposition à simplement obtenir une vue à partir d'un objet personnalisé, tout en prenant en charge l'API 1.5?

Par exemple, disons que j'ai la classe Foo.java:

public class Foo extends Fragment {

    /** Title of the Foo object*/
    private String title;
    /** A description of Foo */
    private String message;

    /** Create a new Foo
     * @param title
     * @param message */
    public Foo(String title, String message) {
        this.title = title;
        this.message = message;
    }//Foo

    /** Retrieves the View to display (supports API 1.5. To use,
     * remove 'extends Fragment' from the class statement, along with
     * the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}) 
     * @param context Used for retrieving the inflater */
    public View getView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//getView 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//onCreateView

}//Foo

Les deux méthodes sont très simples à créer et à utiliser dans une activité qui, par exemple, a un List<Foo>à afficher (par exemple, en ajoutant chacune par programme à a ScrollView), sont donc Fragmentsvraiment très utiles, ou sont-elles juste une simplification exagérée de obtenir une vue, comme par le biais du code ci-dessus?

Phil
la source
2
Les fragments n'ont pas besoin d'avoir une interface utilisateur, ils peuvent simplement être un comportement réutilisable. Une vue serait redondante dans ce cas.
Philipp Reichart
J'ai répondu à cela dans une autre question. Voir stackoverflow.com/a/14912608/909956 T; dr - parfois, les fragments vous permettent de créer plus de composants réutilisables que de compter sur l'implémentation de vues personnalisées. voir le lien pour savoir pourquoi.
numan salati

Réponses:

172

La principale raison d'utiliser des fragments est pour les fonctionnalités de backstack et de cycle de vie. Sinon, les vues personnalisées sont plus légères et plus simples à mettre en œuvre.

Au début, j'ai en fait essayé de créer une application pour téléphone / tablette en utilisant des vues personnalisées. Tout semblait fonctionner sur les téléphones ET les tablettes, même en passant d'un panneau unique à un panneau divisé. Là où j'ai rencontré des problèmes, c'était avec le bouton de retour et le cycle de vie. Puisque je mettais simplement à jour les vues manuellement ... il n'y avait rien qui gardait l'historique des vues et de leurs états. Par conséquent, le bouton de retour ne fonctionnait pas comme prévu et il était difficile de recréer même le dernier état pendant les événements du cycle de vie, comme lors de la rotation de l'application. Pour résoudre ce problème, j'ai dû envelopper mes vues personnalisées dans des fragments et utiliser le FragmentManager afin que les états précédents soient enregistrés et recréés.

J'ai réalisé après avoir répondu que j'avais posté une question similaire un an plus tôt: https://stackoverflow.com/a/11126397/618881

Henri
la source
14
Très bonne réponse. Je voulais juste ajouter que les fragments peuvent être imbriqués depuis la version 4.2 ou supporte la bibliothèque rev 11.
kar
2
Merci @Karlo pour la mise à jour. Je ne pensais pas que c'était conceptuellement possible, mais ils l'ont contourné en utilisant un FragmentManager privé via getChildFragmentManager (). Oh, et c'est l'API 17, pas 11, et disponible via la bibliothèque de support.
Henry
2
Je regardais à nouveau cette question et mon expérience a également changé. C'est une réponse qui fournit une bonne compréhension des avantages et des inconvénients, et qui est très utile. Merci!
Phil
2
Vous voulez attribuer +1 à cette réponse, mais cela ruinerait le score actuel. D'ailleurs, 70 n'est pas mon chiffre préféré.
Behnam
1
pour l'année dernière, je pensais également que Fragments ne fournissait aucune fonctionnalité extra ordinaire, mais j'ai constaté qu'après avoir reculé sur l'activité, je perdais toutes les images téléchargées, donc j'ai dû ajouter une implémentation de cache, maintenant je pense utiliser fragments il peut être très facile
Shirish Herwade
27

Je dirais que les fragments sont utiles dans deux scénarios: si vous divisez les vues sur certains appareils / orientations et les montrez en deux activités et affichez tout le contenu dans une sur d'autres appareils. Ce serait un cas d'utilisation si vous allez sur une tablette ou peut-être même en mode paysage sur un téléphone: par exemple, vous affichez la liste des éléments et les détails sur un seul écran. sur un téléphone ou en mode portrait, vous ne montrez qu'une partie.

Un autre cas d'utilisation concerne les vues réutilisables. Donc, si vous avez des vues visibles sur différentes activités et que vous effectuez également des actions, vous pouvez mettre ce comportement dans un fragment et le réutiliser. De toute évidence, vous pouvez probablement le faire avec des widgets personnalisés.

Je ne verrais aucune raison d'utiliser des fragments pour chaque vue et je suppose que ce serait juste une surcharge. Je ne les utilise que dans le premier cas d'utilisation et je dirais ici que c'est une simplification.

Maria Neumayer
la source
Merci, cela a été vraiment utile. Je pense que je vais m'en tenir aux vues et créer ma propre «pile arrière» pour les rendre réutilisables.
Phil
3

Android a introduit des fragments dans Android 3.0 (niveau d'API 11), principalement pour prendre en charge des conceptions d'interface utilisateur plus dynamiques et flexibles sur de grands écrans, tels que les tablettes. Étant donné que l'écran d'une tablette est beaucoup plus grand que celui d'un combiné, il y a plus de place pour combiner et échanger les composants de l'interface utilisateur. Les fragments permettent de telles conceptions sans que vous ayez à gérer des modifications complexes de la hiérarchie des vues. En divisant la disposition d'une activité en fragments, vous pouvez modifier l'apparence de l'activité au moment de l'exécution et conserver ces modifications dans une pile arrière gérée par l'activité.

Ici vous pouvez en savoir plus.

Yury
la source
J'ai lu toute la documentation, mais je cherchais quelque chose qui explique mieux leur avantage, comme pour les tablettes ou la backstack
Phil
3
  1. Écran partagé d'activité de scénario - Nous avons une mise en page et une activité qui gèrent la partie gauche de l'écran à droite
  2. Fragment de scénario: Activité, nous avons une disposition pour l'écran principal, une pour la gauche et une pour la droite

Le premier scénario est bon si vous avez une application simple.

Le scénario deux est bon si vous souhaitez avoir plusieurs fragments et plusieurs FragmentActivities et que vous pouvez combiner chacun d'entre eux. Vous pouvez également faire une interaction entre les fragments.

J'ai un écran partagé Fragmentactivity, je peux l'appeler avec «Intent Extras» et dire à fragmentActivity quel fragment doit être chargé. Les fragments sont bons car ils ne sont pas dans le manifeste, vous pouvez donc créer des fragments réutilisables et FragmentActvity.

Mais cela agrandit votre projet. Mais si vous faites de gros projets, vous pouvez en sauver beaucoup. Parce que vous pouvez utiliser les mêmes fragments ou la même activité de fragments.

Et je pense que ces fragments arrivent un peu tard, vous devez donc essayer de penser d'une manière nouvelle. Essayez peut-être simplement de convertir votre activité en FragmentActivity. Plus tard, essayez de trouver du code réutilisable et faites-en un fragment.

C'est utile mais je ne sais pas comment pour le moment. Mais j'ai quelques idées.

C'est toujours un problème. L'équipe Android a fait quelque chose et personne ne sait à quoi cela sert. Parce que nous apprenons à peine comme c'était le cas et voici quelques nouveautés.

À mon avis, c'est bien mais pas pour la raison que Google nous dit.

Mertuarez
la source
0

Ajoutez un cas lorsque vous utilisez Fragment ou Activity sur CustomView:

Lorsque vous utilisez CursorLoader pour observer certaines vues, ListView ou TextView et que vous souhaitez mettre à jour leur valeur d'affichage chaque fois que les données de votre ContentProvider sont mises à jour en arrière-plan (le cas le plus courant est que vous disposez d'un service qui met à jour votre base de données locale en interrogeant périodiquement les données de la base de données distante / cloud )

macio.Jun
la source
-2

Une grande chose que tous les commentaires ci-dessus ne mentionnent pas est qu'un fragment reste résident en mémoire même si Android tue l'activité et la redémarre lorsque vous faites quelque chose comme changer l'orientation de votre appareil. Ceci est fait pour des raisons de performances, mais peut également conduire à des résultats inattendus si vous vous attendiez à ce que les fragments soient détruits pour constater qu'ils sont recréés de nulle part.

AndroidDev
la source