How can I have a bottom navigation appended not on all the screens in Flutter?

Issue

I was trying to implement the navigation between screens. I have the first screen, where the user must insert the invitation code. At this point user is not authorised yet, and I don’t want him/her to use the bottom navigation bar.
Here is my implementation of the navigation:

home_view.dart

import 'package:fauna/app/styles/colors.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';

import 'home_view_model.dart';

class HomeView extends GetView<HomeController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
        key: Get.nestedKey(1),
        initialRoute: '/invite-code',
        onGenerateRoute: controller.onGenerateRoute,
      ),
      bottomNavigationBar: Obx(() => BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(
                  FontAwesomeIcons.baby,
                  color: vaccineValid,
                  size: 15,
                ),
                title: Text('Pet details'),
              ),
              BottomNavigationBarItem(
                icon: Icon(
                  FontAwesomeIcons.airbnb,
                  color: vaccineValid,
                  size: 15,
                ),
                title: Text('Vet profile'),
              ),
            ],
            currentIndex: controller.currentIndex.value,
            selectedItemColor: Colors.green,
            onTap: controller.changePage,
          )),
    );
  }
}

home_binding.dart

import 'package:fauna/app/modules/home/home_view_model.dart';
import 'package:get/get.dart';

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(() => HomeController());
  }
}

home_controller.dart

import 'package:fauna/app/modules/invite_code/invite_code_binding.dart';
import 'package:fauna/app/modules/invite_code/invite_code_view.dart';
import 'package:fauna/app/modules/pet_details/pet_details_binding.dart';
import 'package:fauna/app/modules/pet_details/pet_details_view.dart';
import 'package:fauna/app/modules/vet_profile/vet_profile_binding.dart';
import 'package:fauna/app/modules/vet_profile/vet_profile_view.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomeController extends GetxController {
  late BuildContext context;

  static HomeController get to => Get.find();
  var currentIndex = 0.obs;
  final pages = <String>['/pet-details', '/vet-profile'];
  var count = 0.obs;

  void changePage(int index) {
    currentIndex.value = index;
    Get.toNamed(pages[index], id: 1);
  }

  Route? onGenerateRoute(RouteSettings settings) {
    if (settings.name == '/invite-code') {
      return GetPageRoute(
        settings: settings,
        page: () => InviteCodeView(),
        binding: InviteCodeBinding(),
      );
    }

    if (settings.name == '/pet-details') {
      return GetPageRoute(
        settings: settings,
        page: () => PetDetailsView(),
        binding: PetDetailsBinding(),
      );
    }

    if (settings.name == '/vet-profile') {
      return GetPageRoute(
        settings: settings,
        page: () => VetProfileView(),
        binding: VetProfileBinding(),
      );
    }
    return null;
  }
}

Solution

If you don’t want to disappear after navigating to any screen when onTap bottom navigation item, you must don’t use GetPageRoute vb. Firstly, create ‘HostView’ and PetDetailsView, VetProfileView pass to body of scaffold. Change dynamically showing index with IndexedStack. So, you navigate to HostView after authenticate user.
I added an example code for you below.

class HostView extends StatefulWidget {
  const HostView({Key? key}) : super(key: key);

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

class _HostViewState extends State<HostView> {
  int _selectedIndex = 0;
  final _pages =  <Widget>[];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _selectedIndex,
        children: _pages,
      ),
      bottomNavigationBar: BottomNavigationBar(
        onTap: (int index) => setState(() => _selectedIndex = index),
        currentIndex: _selectedIndex,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.add),
            label: 'Pet Details',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add),
            label: 'Profile',
          ),
        ],
      ),
    );
  }
}


Answered By – Salih Can

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *