MarcoL
MarcoL

Reputation: 11

How to have a BottomNavigationBar show on more than just the main screens, but not all screens?

Currently it only shows on main screens. I can only get it working on either ALL screens or only main screens... I need to be able to choose which screens to show the BottomNavigationBar on.

I now observe the routing in main.dart and handle the rest of the navigation bar logic in a file I call NavigationConduit.

I have a feeling the RouteObserver is not working properly, already not on the main screens... What am I doing wrong in this approach?

Is there a better way, without having to put code in every screen's initState and dispose?

This is my main.dart, reduced to only show related code:

import 'package:flutter/material.dart';
import 'package:app/navigation_conduit.dart';
import 'package:app/screens/profile/settings_1_overview.dart';
import 'package:app/screens/auth/change_password_1_current.dart';

final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App',
      navigatorObservers: [routeObserver],
      home: const NavigationConduit(),
      routes: {
        '/screens/profile/settings_1_overview': (context) => const SettingsOverview(),
        '/screens/auth/change_password_1_current': (context) => const ChangePasswordScreen(),
      },
    );
  }
}

And then this is my navigation_conduit.dart:

import 'package:flutter/material.dart';
import 'package:app/screens/home/home_screen.dart';
import 'package:app/screens/overview/overview.dart';
import 'package:app/screens/scanner/scanner.dart';
import 'package:app/screens/favorites/favorites_overview.dart';
import 'package:app/screens/profile/user_profile.dart';
import 'package:app/screens/profile/settings_1_overview.dart';
import 'package:app/screens/auth/change_password_1_current.dart';

class NavigationConduit extends StatefulWidget {
  const NavigationConduit({super.key});

  @override
  _NavigationConduitState createState() => _NavigationConduitState();
}

class _NavigationConduitState extends State<NavigationConduit> with RouteAware {
  int _selectedIndex = 0;
  bool _showBottomNavBar = true;

  final List<Widget> _screens = [
    const HomeScreen(),
    const Overview(),
    const Scanner(),
    const FavoritesOverview(),
    const UserProfile(),
  ];

  void _onItemTapped(int index) {
    if (_selectedIndex == index) {
      Navigator.of(context).popUntil((route) => route.isFirst);
    } else {
      setState(() {
        _selectedIndex = index;
        _showBottomNavBar = true;
      });
    }
  }


  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final ModalRoute? route = ModalRoute.of(context);
    setState(() {
      _showBottomNavBar = _shouldShowBottomNavBar(route);
    });
  }


  bool _shouldShowBottomNavBar(Route<dynamic>? route) {
    if (route == null) return true;
    final currentRouteName = route.settings.name ?? '';
    print('Checking route: $currentRouteName');
    return ![
      '/screens/profile/settings_6_info',
      '/screens/auth/change_password_1_current',
    ].contains(currentRouteName);
  }


  @override
  void didPush() {
    super.didPush();
    setState(() {
      _showBottomNavBar = _shouldShowBottomNavBar(ModalRoute.of(context));
    });
  }


  @override
  void didPopNext() {
    super.didPopNext();
    setState(() {
      _showBottomNavBar = _shouldShowBottomNavBar(ModalRoute.of(context));
    });
  }


  @override
  void dispose() {
    super.dispose();
  }


  String getIconAsset(int index, bool isSelected) {}
  // This gets all the images connected to the right icons


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _screens[_selectedIndex],
      bottomNavigationBar: _showBottomNavBar
          ? Container(
        decoration: const BoxDecoration(
          border: Border(
            top: BorderSide(color: Color(0xFFA4A4A4), width: 1.0),
          ),
          color: Colors.white,
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: List.generate(5, (index) {
            bool isSelected = _selectedIndex == index;
            return IconButton(
              icon: Image.asset(
                getIconAsset(index, isSelected),
                width: 24.0,
                height: 24.0,
              ),
              onPressed: () {
                _onItemTapped(index);
              },
            );
          }),
        ),
      )
          : null,
    );
  }
}

Upvotes: 1

Views: 71

Answers (0)

Related Questions