Disposition du coordinateur avec barre d'outils dans les fragments ou l'activité

94

Avec la nouvelle bibliothèque de design, plusieurs nouvelles mises en page modifient considérablement le comportement de la barre d'outils si le développeur le souhaite. Étant donné que différents fragments ont des comportements et des objectifs différents, par exemple un fragment de galerie avec une barre d'outils de réduction montrant une photo importante, ou un fragment sans vue de défilement qui n'a tout simplement pas besoin de la disposition de la barre d'applications pour masquer la barre d'outils, avoir une seule barre d'outils dans l'activité peut s'avérer difficile.

Donc, avec cela, dois-je déplacer la barre d'outils vers chaque fragment? Si tel est le cas, je dois définir le supportActionBar chaque fois que je montre un fragment et avoir également une référence de l'activité dans le fragment qui annule le caractère indépendant des fragments. Si je laisse la barre d'outils dans l'activité seule, je dois avoir plusieurs mises en page définies pour chaque type de comportement dans chaque fragment. Quelle serait la meilleure approche?

mobilepotato7
la source
1
Salut, avez-vous trouvé une solution?
SERG
2
pour mon projet actuel, j'ai décidé de m'en tenir à la barre d'outils de l'activité et de faire les animations appropriées si nécessaire. Mais c'est un peu compliqué. J'ai essayé d'utiliser la barre d'outils dans chaque fragment et cela fonctionne bien, mais animer la barre d'outils entre les transitions de fragments est plus difficile et je ne sais même pas si c'est possible car je n'ai pas beaucoup d'expérience avec les animations de transitions de fragments.
mobilepotato7
des mises à jour ou de meilleures solutions à cela maintenant?
Sagar Nayak

Réponses:

56

Quant à moi, cela semble trop étrange d'avoir une barre d'applications et une barre d'outils dans chaque fragment. J'ai donc choisi d'avoir une seule barre d'applications avec une barre d'outils en activité.

Pour résoudre ce problème avec CoordinatorLayout, vous devrez définir un comportement différent de votre FrameLayout(ou de toute autre mise en page) qui est censé contenir des fragments de chaque fragment que vous souhaitez remplacer le comportement par défaut.

Supposons que votre comportement par défaut est app:layout_behavior="@string/appbar_scrolling_view_behavior"

Ensuite, dans votre fragment_activity_layout.xml, vous pouvez avoir quelque chose comme ça:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/dashboard_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.Toolbar"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/dashboard_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

Et dans chaque fragment que vous ne souhaitez pas implémenter, app:layout_behavior="@string/appbar_scrolling_view_behavior"vous devrez remplacer onAttachet des onDetachméthodes qui modifieront le comportement de votre FrameLayout:

CoordinatorLayout.Behavior behavior;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if(behavior != null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    behavior = params.getBehavior();
    params.setBehavior(null);

}

@Override
public void onDetach() {
    super.onDetach();
    if(behavior == null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    params.setBehavior(behavior);

    layout.setLayoutParams(params);

    behavior = null;
}

Après cela, CoordinatorLayout ne réduira pas la barre d'applications, etc. et permettra aux mises en page de fragment d'être pleine hauteur.

Клаус Шварц
la source
Gentil, devra essayer ceci et voir si cela simplifie les choses. Merci.
mobilepotato7
Si vous trouvez quelque chose de plus simple, faites-le moi savoir. Je pense qu'il est possible de changer le comportement du coordinateur à tout moment pendant le cycle de vie des fragments (par exemple, vous avez normalement un recycleur avec des choses, mais dans de rares cas, il peut être vide et vous saurez que seulement après Loader onLoadFinished, il est possible que vous aime montrer une image centrée indiquant que rien n'est ici, comme dans l'application Inbox), mais je n'ai pas encore essayé cela. Peut-être plus tard aujourd'hui.
Клаус Шварц
Ok, ça marche plutôt bien. J'ai créé un assistant qui s'occupe d'activer / désactiver le coordinateur le cas échéant, donc je viens d'appeler enableCoordinator(Activity activity)/ à disableCoordinator(Activity activity)partir de fragments.
Клаус Шварц
Où est votre aide, @ КлаусШварц? Quand l'appelles-tu?
santhyago
1
@santhyago dans le fragment
Клаус Шварц
8

Voici ma solution

<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- Your fragment -->
    <include layout="@layout/content_main" />

</FrameLayout>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

Charles-Eugène Loubao
la source
1

C'est une très bonne question: faut-il Toolbarque s qui doivent agir comme un ActionBarêtre conservé dans un Activityou unFragment ? Après avoir recherché différentes questions et documentation, je n'ai pas trouvé de solution qui couvre tous les cas. Le chemin à parcourir dépend donc vraiment de votre situation.

Cas 1: la barre d'outils doit remplacer ActionBar

Si la barre d'outils doit se comporter comme une ActionBar normale (ou si 1 fragment maximum est affiché de temps en temps), je pense que la meilleure / la plus simple est d'utiliser la traditionnelle Activities avec sa propre barre d'outils et d'y placer votre fragment. De cette façon, vous n'avez pas à vous soucier du moment où la barre d'outils doit être affichée.

Changer l'ActionBar (-behaviour) de Fragments est également possible, mais je ne le recommanderais pas, car cela vous oblige à garder une trace de quel Fragment a changé l'ActionBar quand. Je ne sais même pas si la configuration de l'ActionBar peut être effectuée plusieurs fois.

Cas 2: chaque fragment doit avoir sa propre (partie de) barre d'outils

Vous pouvez également choisir de placer différentes barres d'outils autonomes dans différents fragments, avec leurs propres actions. De cette façon, vous pouvez afficher différents fragments les uns à côté des autres - chacun avec ses propres actions dans sa barre d'outils - et suggérer qu'il s'agit d'une barre d'outils (peut-être comme l'application Gmail, bien que je ne sois pas sûr). Cela signifie cependant que vous devrez gonfler ces barres d'outils vous-même, mais cela ne doit pas être très difficile.

J'espère que cela aidera à faire un choix.

(Désolé si j'ai fait des erreurs (de langue))

Coen B
la source
4
désolé mais cela ne répond pas vraiment aux problèmes relatifs à la nouvelle bibliothèque de design. Bien sûr, avoir la barre d'outils comme barre d'actions est l'objectif, mais avoir plusieurs mises en page de coordinateur pour différents types de barres d'outils peut être délicat. Ce que j'ai trouvé, c'est qu'il est possible d'animer la barre d'outils selon les besoins. J'ai encore besoin de mieux le tester mais il semble qu'il y ait de bons résultats
mobilepotato7