Bottom Tab Bar et router

J’ai eu une approche différente. Je crée la bottomNavigationBar dans mon navigatorDelegate.

La fonction build de mon navigateurDelegate retourne un scaffold contenant la bottom navigation bar et le body contient le navigator avec la liste des pages. Le navigateurDelegate gère également la bottomNavigationBar

Widget build(BuildContext context) {
    List<MaterialPage> pagesList = [];

    if (_bottomNavigationBarIndex == 0) {
      pagesList.add(MaterialPage(
          child: AccountScreen(
        viewModel: AccountViewModel(),
      )));
    } else if (_bottomNavigationBarIndex == 1) {
      pagesList.add(MaterialPage(
          child: MessagesListeScreen(
        viewModel: MessagesListViewModel(router: this),
      )));

      if (_message != null) {
        pagesList.add(MaterialPage(
            child: MessageDetailsScreen(
                viewModel: MessageDetailsViewModel(
                    message: _message!, router: this))));
        leading = IconButton(
          icon: const Icon(Icons.chevron_left),
          onPressed: () => onBackButtonTouched(null),
        );
      }
    }

    return Scaffold(
      bottomNavigationBar: CustomBottomNavigationBar(router: this),
      body: Navigator(
        pages: pagesList,
        onPopPage: (route, result) {
          if (!route.didPop(result)) {
            return false;
          }
          return onBackButtonTouched(result);
        },
      ),
    );
  }

ensuite dans les écrans affichés, build retourne également un scaffold mais sans la navigation bar.

Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: const Text("Mes messages")),
        body: ListView.builder(
          itemBuilder: viewModel.generateMessageTile,
          itemCount: viewModel.messagesList.length,
        ));
  }

J’ai un écran liste qui permet d’afficher les détails des éléments de cette liste. En faisant de cette façon, la bottom navigation bar ne glisse pas avec le reste de l’écran.

1 « J'aime »

Merci @jmjoary pour ta remarque :slight_smile:

Effectivement, sur chaque page, je rajoute le BottomNavigationBar… aucun intérêt !
C’est très judicieux de l’avoir rajouté dans le navigator delegate.

J’ai voulu faire la même chose mais … j’ai comme un problème :frowning:

No overlay widget found. BottomNavigationBar widgets require an overlay widget ancestor for correct operation.

Message que je n’ai pas dans ma config actuelle.
Tu return quelque chose de particulier dans ton CustomBottomNavigationBar ou (comme moi) un simple BottomNavigationBar ?

 @override
  Widget build(BuildContext context) {
    return 
     BottomNavigationBar(

Merciiiiiiii beaucoup :slight_smile:

ps : je viens de me rendre compte d’un tout autre problème que j’ai en rapport avec mon BottomNavigationBar (au cas où ca parle à quelqu’un) :slight_smile:
Sur une page (flutter_map), lorsque je suis en attente de localisation (CircularProgressIndicator) et que je change de page, flutter tombe en anomalie dans la méthode dispose() :

FlutterError (setState() called after dispose()

Tu return quelque chose de particulier dans ton CustomBottomNavigationBar ou (comme moi) un simple BottomNavigationBar ?

Non pas vraiment. J’utilise juste le paquet salomon_bottom_bar pour crée ma bottom navigation bar.

Peux-tu mettre le code du build de ton navigation delegate pour que l’on puisse voir ce qui se passe ?

1 « J'aime »

Génial @jmjoary !!! Trop fort :slight_smile:

Du coup, j’utilise maintenant la superbe barre de navigation ‹ salomon_bottom_bar › de cette manière :

    return SafeArea(
      child: Scaffold(
        body: Navigator(
          key: navigatorKey,
          pages: pagesList,
          onPopPage: (route, result) {
            if (route.didPop(result) == false) {
              return false;
            }
            return onBackButtonTouched(result);
          },
        ),
        bottomNavigationBar: BottomMenu(
          router: this,
          selected: _selected,
        ),
      ),
    );
  }

et BottomMenu retourne :

  @override
  Widget build(BuildContext context) {
    return SalomonBottomBar(

Merci beaucoup :slight_smile:

Il semble que pour la BottomNavigationBar il y ai un souci …
Si on considère l’arbre des widgets suivants :

MaterialApp.router:
  RouterDelegate:
    Scaffold:
      body = Navigator
      bottomNavigationBar = BottomNavigationBar

Il y a dans ce cas un problème d’ancêtre Overlay … et on obtient une erreur :

No overlay widget found. BottomNavigationBar widgets require an overlay widget ancestor for correct operation.

En utilisant la < salomon_bottom_bar > on contourne le problème car il s’agit d’un ‹ simple › widget.

Pour ma part, ne voulant par utiliser cette dépendance et surtout pouvoir rester maître du design de la Bar, j’ai créé un widget MyCustomNavigationBar qui retourne un BottomAppBar

 Widget build(BuildContext context) {
    return BottomAppBar(
      child: Row(children: <Widget>[
        IconButton( ...)
        ...
       ]),);

et bien sur je branche le bottomNavigationBar de mon scaffold retourné par mon Navigator dessus

Navigator(
          key: navigatorKey,
          pages: pagesList,
         bottomNavigationBar: MyCustomNavigationBar(),
         ....

ça marche nickel ! :grinning:

1 « J'aime »

Merci Philippe pour ton explication :slight_smile: