web-dev-qa-db-fra.com

Flutter: Gardez BottomNavigationBar lorsque vous poussez vers un nouvel écran avec Navigator

Dans iOS, nous avons un ITabBarController qui reste en permanence en bas de l'écran lorsque nous poussons vers un nouveau ViewController.

Dans Flutter, nous avons une barre de navigation inférieure d'un échafaudage. Cependant, contrairement à iOS, lorsque nous Navigator.Push vers un nouvel écran, cette barre de navigation inférieure disparaît.

Dans mon application, je veux remplir cette condition: l'écran d'accueil a un bottomNavigationBar avec 2 éléments ( a & b ) écran de présentation [~ # ~] a [~ # ~] & [~ # ~] b [~ # ~] . Par défaut, l'écran [~ # ~] a [~ # ~] s'affiche. Écran intérieur [~ # ~] a [~ # ~] , il y a un bouton. Appuyez sur ce bouton, Navigator.Push à l'écran [~ # ~] c [~ # ~] . Maintenant dans l'écran [~ # ~] c [~ # ~] , nous pouvons toujours voir le bottomNavigationBar. Appuyez sur l'élément b , je vais à l'écran [~ # ~] b [~ # ~] . Maintenant dans l'écran [~ # ~] b [~ # ~] , appuyez sur l'élément a dans le bottomNavigationBar, je reviens à l'écran [~ # ~] c [~ # ~] (not [~ # ~] a [~ # ~] , [~ # ~] a [~ # ~] est actuellement en dessous [~ # ~] c [~ # ~] dans la hiérarchie de navigation).

Comment puis-je faire ceci? Merci les gars.

Edit: j'inclus quelques photos pour démonstration:

Écran A Écran A

Appuyez sur Allez sur le bouton C , appuyez sur l'écran C écran C

Appuyez sur Élément droit dans la barre de navigation inférieure, allez à l'écran B Écran B

8
kcatstack

tl; dr: utilisez CupertinoTabBar avec CupertinoTabScaffold

Le problème n'est pas dans Flutter mais dans UX comme Rémi Rousselet l'a mentionné.

Il s'est avéré que Material Design ne recommande pas les sous-pages de la hiérarchie pour accéder à la barre de navigation inférieure.

Cependant, le Guide de l'interface humaine iOS le recommande. Donc, pour utiliser cette fonctionnalité, j'ai dû adapter les widgets Cupertino au lieu de ceux matériels. Plus précisément, en général, renvoyez un WidgetsApp/MaterialApp qui contient un CupertinoTabScaffold. Implémentez la barre d'onglets avec un CupertinoTabBar et chaque écran est un CupertinoTabView.

9
kcatstack

Vous devez créer MaterialApp avec des itinéraires et faire de BottomNavigationBar un frère de celui-ci. Utilisez ensuite MaterialApp.navigatorKey que vous transmettez à BottomNavigationBar pour effectuer la navigation.

https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5

7
robotoaster

Vous pouvez en fait placer un espace réservé à l'intérieur du corps pour que la structure comme celle-ci

- AppBar
- body (dynamic content from placeholder)
- BottomNavigationBar

Ensuite, vous auriez une autre classe en tant qu'espace réservé. Ainsi, chaque fois que vous appuyez sur la barre de navigation inférieure, elle actualise le contenu du corps.

Un exemple que j'ai trouvé est ici https://willowtreeapps.com/ideas/how-to-use-flutter-to-build-an-app-with-bottom-navigation

et ici, mais un peu trop complexe et ne fonctionne pas pour moi https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5

et cela https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf

3
stuckedoverflow

Je pense que la bonne façon de procéder serait d'avoir le BottomNavigationBar enveloppé dans un Hero dans les deux cas avec la même balise. De cette façon, lorsque l'animation entre les pages se produit, elles sont exclues.

C'est aussi bref qu'un exemple que je pourrais faire, mais je recommande fortement de le nettoyer, c'est-à-dire de passer la chaîne de héros, en utilisant des widgets plutôt qu'un énorme bloc de construction, créant votre propre widget pour BottomNavigationBar.

Notez que pendant la transition des héros, il ne overflow by 0.0000191 pixels sur mon téléphone au moins, mais en mode de libération, cela ne devrait pas être un problème, je ne pense pas.

importer 'package: flutter/material.Dart';

void main() => runApp(new MaterialApp(
      home: new Builder(
        builder: (context) => new Scaffold(
              bottomNavigationBar: new Hero(
                tag: "bottomNavigationBar",
                child: new BottomNavigationBar(items: [
                  new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Home")),
                  new BottomNavigationBarItem(icon: new Icon(Icons.ac_unit), title: new Text("AC Unit"))
                ]),
              ),
              body: new SafeArea(
                child: new Container(
                  constraints: new BoxConstraints.expand(),
                  color: Colors.green,
                  child: new Column(
                    children: <Widget>[
                      new RaisedButton(
                          child: new Text("Press me"),
                          onPressed: () {
                            Navigator.Push(
                                context,
                                new MaterialPageRoute(
                                    builder: (context) => new Scaffold(
                                          bottomNavigationBar: new Hero(
                                            tag: "bottomNavigationBar",
                                            child: new BottomNavigationBar(items: [
                                              new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Home")),
                                              new BottomNavigationBarItem(icon: new Icon(Icons.ac_unit), title: new Text("AC Unit"))
                                            ]),
                                          ),
                                          body: new SafeArea(
                                            child: new Container(
                                              constraints:
                                                  new BoxConstraints.expand(),
                                              color: Colors.red,
                                              child: new Column(
                                                children: <Widget>[
                                                  new RaisedButton(
                                                    onPressed: () =>
                                                        Navigator.pop(context),
                                                    child: new Text("Back"),
                                                  )
                                                ],
                                              ),
                                            ),
                                          ),
                                        )));
                          })
                    ],
                  ),
                ),
              ),
            ),
      ),
    ));

Je ne sais pas dans quelle mesure le système hero gère plusieurs héros, etc., et si vous dites vouloir animer la barre de navigation, cela pourrait ne pas fonctionner trop bien.

Il existe une autre façon de procéder qui vous permettrait d'animer la barre de navigation inférieure; c'est en fait une question à laquelle on a déjà répondu: Flutter: transition de héros + animation de widget en même temps?

2
rmtmckenzie

Une autre façon d'y parvenir (bien que ce ne soit pas une bonne pratique) consiste à imbriquer une application matérielle dans le corps de votre échafaudage. Et gérez toutes les "sous-navigation" là-bas.

Donc, votre hiérarchie ressemblera à ceci

Material App
  - home
     - Scaffold
       - body
         - Material App
              - Scaffold
                  - AppBar
                  - body
                  ...
         - routes (internal)
       - bottomNavigationBar
  - routes (external)

J'ai essayé cela et cela fonctionne parfaitement. Malheureusement, je ne peux pas publier le code source maintenant.

1
Kingsley Kbc Comics

Vous pouvez créer un widget Navigator dans un widget Stack pour utiliser BottomNavigationBar avec la navigation interne des onglets. Vous pouvez utiliser WillPopScope pour gérer le bouton de retour d'Android pour faire apparaître les écrans intérieurs de l'onglet. En outre, appuyez deux fois sur l'élément de navigation inférieur pour faire apparaître tous les écrans intérieurs d'un onglet.

J'ai créé un exemple d'application pour cela.

J'espère que cette aide!

0
Hemant Kaushik

J'ai créé un petit paquet super facile à utiliser qui vous permet de faire cet effet CustomNavigator Et j'ai écrit un tutoriel à ce sujet sur Medium, vous pouvez le trouver ici

0
Ayham Orfali