web-dev-qa-db-fra.com

Composant d'architecture de navigation - Vue détaillée avec CollapsingToolbar

La pratique proposée pour les nouveaux composants de navigation a été présentée aux E/S avec le modèle et la philosophie proposés suivants:

  1. Une activité pour une application
  2. L'activité contient la barre d'outils et la barre de navigation inférieure

Une application typique comporte souvent une vue détaillée avec une barre d'outils CollapsingTool. Comment pourrait-on construire cela sous cette architecture?

  • Déplacer la barre d'outils vers chaque fragment XML?
  • Implémenter la barre d'outils de réduction par programme?
  • Déplacer le fragment de détail vers sa propre activité (il peut de toute façon utiliser son propre lien profond) et "casser" la philosophie?
29
Julian

Une application typique a souvent une vue détaillée avec une barre d'outils CollapsingTool. Comment pourrait-on construire cela sous cette architecture?

Grande question! Je me suis également débattu un peu avec cela et je suis arrivé à la conclusion qu'il devrait y avoir une activité avec NavHostFragment et, idéalement, rien d'autre. Cela vous donne une flexibilité ultime pour afficher (ou ne pas afficher) tout ce dont vous avez besoin pour chaque écran. Surtout, assurez-vous que votre thème supprime l'ActionBar:

<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

Ce qui vous amène à votre prochaine question ...

Déplacer la barre d'outils vers chaque fragment XML?

À mon avis, ouais! Tout ce que vous utiliseriez généralement l'ActionBar peut être fait via une barre d'outils. Voici un extrait rapide qui montre comment une barre d'outils peut être utilisée pour faire les choses les plus importantes pour lesquelles vous avez utilisé ActionBar dans le passé (navigation vers le haut, titre, menu d'options, etc ...):

toolbar.apply {
    setNavigationOnClickListener { findNavController().navigateUp() }
    setTitle(R.string.toolbar_title)
    inflateMenu(R.menu.fragment_menu)
    setOnMenuItemClickListener(::onMenuItemClick)
}

Implémenter la barre d'outils de réduction par programme?

Cela dépend de ce que vous essayez de faire exactement, mais très probablement, cela n'est pas nécessaire. Vous pouvez déposer un AppBarLayout, CollapsingToolbarLayout et Toolbar dans votre mise en page et les utiliser comme d'habitude. Donnez à votre AppBarLayout une superposition de thème ActionBar. Voici un exemple:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/coordinatorLayout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <com.google.Android.material.appbar.AppBarLayout
        Android:id="@+id/appBarLayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.Android.material.appbar.CollapsingToolbarLayout
            Android:id="@+id/collapsingToolbarLayout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            app:contentScrim="@color/primary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <androidx.appcompat.widget.Toolbar
                Android:id="@+id/toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:navigationIcon="@drawable/ic_up_white"/>

            ...

Déplacer le fragment de détail vers sa propre activité (il peut de toute façon utiliser son propre lien profond) et "casser" la philosophie?

Pas besoin de ça avec ce qui précède, non? C'est une approche suffisamment flexible pour s'adapter facilement à plusieurs niveaux dans un seul graphique de navigation et toujours en mesure de personnaliser l'apparence et le comportement de chaque destination dans le graphique (y compris la fonctionnalité de type ActionBar).

3
mtrewartha

essayer

appBarLayout = (AppBarLayout) findViewById(R.id.appbar);


if(expandToolbar){
                appBarLayout.setExpanded(true,true);
            }else{
                appBarLayout.setExpanded(false,true);
            }

Voici un lien usufal désactiver le développement sur CollapsingToolbarLayout pour certains fragments

également pour d'autres personnes souhaitant changer certaines parties de leur barre d'outils, vous devez écrire votre vue de barre d'outils personnalisée dans du XML séparé et essayer de gonfler la vue personnalisée dans vos détails Fragmentez grammaticalement puis masquez les éléments inutilisés de l'ancienne barre d'outils s'il y en a.

setSupportActionBar(toolbar);
View logo = getLayoutInflater().inflate(R.layout.view_logo, null);
toolbar.addView(logo);

et voici comment vous pouvez masquer les vues indésirables

for (int i = 0; i < toolbar.getChildCount(); ++i) {
        View child = toolbar.getChildAt(i);

        // here u can hide all text views for example.
        if (child instanceof TextView) {
            child.setVisibility(View.GONE );
        }
    }

c'est bien mieux que d'écrire deux activités

0
Diaa Saada

Supposons que nous avons

  1. Une activité pour une application
  2. L'activité contient la barre d'outils et la barre de navigation inférieure

Toutes les apparences possibles pour la barre d'outils dont vous avez besoin pour votre application doivent être implémentées dans cette barre d'outils unique et contrôlables comme le fragment actuellement actif. Pour ne pas violer le principe d'inversion de dépendance, tous les fragments qui ont besoin d'une fonctionnalité de la barre d'outils de l'activité doivent implémenter une interface. Vous pouvez utiliser le OnBackStackChangedListener pour vérifier les mises à jour de la vue

getFragmentManager().addOnBackStackChangedListener(
    new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment visibleFragment = ...
            if(visibleFragment instanceof ToolbarControlFragment) {
                if(visibleFragment.shouldExpandToolbar()) {
                    // set AppBarLayout expanded state
                }
                // ...
            }
        }
    }
);

Vous vous souvenez peut-être de ce principe lorsqu'un fragment nécessite un menu d'options.

Je recommanderais généralement d'avoir une seule barre de navigation inférieure contrôlée par une activité et plusieurs barres d'outils dans les fragments. Cela réduit la complexité et rend les composants de l'application plus indépendants.

0
styp