1

I have a Dart file named page0.dart and this only includes a BottomNavigationBar. BottomNavigationBar has 2 items in it which redirects me to dashboard.dart and target.dart, the navigation via the BottomNavigationBar works as expected.

Now the problem: I need a button on dashboard.dart that should redirect me to target.dart, but keep the ButtomNavigationBar visible.

I am redirecting with Navigator.push, but that opens target.dart directly and skips page0.dart I think.

Screenshots are below. Please watch them for better understanding my problem.

Here are the code samples:

page0.dart:

import 'package:flutter/material.dart';
import 'package:navbartest/dashboard.dart';
import 'package:navbartest/target.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key, required String title}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      bottomNavigationBar: BottomNavBar(),
    );
  }
}

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

  @override
  State<BottomNavBar> createState() => _BottomNavBarState();
}

class _BottomNavBarState extends State<BottomNavBar> {
  int _pageIndex = 0;

  final List<Widget> _tabList = const [
    Dashboard(),
    Target(),
  ];

  Widget? onItemTap(int index) {
    setState(() {
      _pageIndex = index;
    });
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        _tabList.elementAt(_pageIndex),
        Padding(
          padding: EdgeInsets.only(right: 35, bottom: 25, left: 35),
          child: Align(
            alignment: const Alignment(0.0, 1.0),
            child: ClipRRect(
              borderRadius: const BorderRadius.all(
                Radius.circular(20),
              ),
              child: BottomNavigationBar(
                backgroundColor: const Color(0xff565656),
                type: BottomNavigationBarType.fixed,
                showSelectedLabels: false,
                showUnselectedLabels: false,
                unselectedItemColor: Colors.white,
                selectedItemColor: Colors.white,
                onTap: onItemTap,
                items: [
                  BottomNavigationBarItem(
                    icon: const Icon(Icons.home),
                    label: "Dashboard",
                  ),
                  BottomNavigationBarItem(
                    icon: const Icon(Icons.car_repair),
                    label: "Target",
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

dashboard.dart

import 'package:navbartest/target.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: Container(
            width: 120,
            height: 20,
            color: Colors.blue,
            child: InkResponse(
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const Target()),
                );
              },
              child: Text('navigate to target'),
            ),
          ),
        ),
      ),
    );
  }
}

target.dart:


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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Text('target'),
      ),
    );
  }
}

when the app is started, it looks like this
when I click the blue button to navigate, it looks like this (NavBar is gone!)
when I click the symbol in the navbar redirecting me to target.dart, it looks like this (thats how I want it with the blue button too!)

lophix
  • 15
  • 4

1 Answers1

0

actually you need to use a state management for this type of actions , but I found a work around in your case , I will set the classes next Just replace them with your classes and it will work.

1 - page0.dart:

import 'target.dart';
import 'package:flutter/material.dart';
import 'dash.dart';

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

  @override
  State<BottomNavBar> createState() => BottomNavBarState();
}

class BottomNavBarState extends State<BottomNavBar> {

  late int _pageIndex;
  late final List<Widget> _tabList;

  Widget? onItemTap(int index) {
    setState(() {
      _pageIndex = index;
    });
    return null;
  }

  @override
  void initState(){
    super.initState();
    _pageIndex = 0;

    _tabList = [
      Dashboard(ref:(int number){
        setState(() {
          _pageIndex = number;
        });
      }),
      const Target(),
    ];
  }
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        _tabList.elementAt(_pageIndex),
        Padding(
          padding: EdgeInsets.only(right: 35, bottom: 25, left: 35),
          child: Align(
            alignment: const Alignment(0.0, 1.0),
            child: ClipRRect(
              borderRadius: const BorderRadius.all(
                Radius.circular(20),
              ),
              child: BottomNavigationBar(
                backgroundColor: const Color(0xff565656),
                type: BottomNavigationBarType.fixed,
                showSelectedLabels: false,
                showUnselectedLabels: false,
                unselectedItemColor: Colors.white,
                selectedItemColor: Colors.white,
                onTap: onItemTap,
                items: [
                  BottomNavigationBarItem(
                    icon: const Icon(Icons.home),
                    label: "Dashboard",
                  ),
                  BottomNavigationBarItem(
                    icon: const Icon(Icons.car_repair),
                    label: "Target",
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}

2 - dashboard.dart :

import 'package:flutter/material.dart';

class Dashboard extends StatelessWidget {
  const Dashboard({super.key, required this.ref});

  final Function(int)? ref ;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: Container(
            width: 120,
            height: 20,
            color: Colors.blue,
            child: InkResponse(
              onTap: ()=>ref!(1),
              child: Text('navigate to target'),
            ),
          ),
        ),
      ),
    );
  }
}

3 - target.dart:

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Text('target'),
      ),
    );
  }
}

remove the import and re import for the right paths in your application file , but this is a work around and you should use the state management .

Ahmad Ellamey
  • 331
  • 2
  • 7
  • Thank you for your answer! Your answer works for me. However I tried to implement a statelessWidget which includes the body of dashboard.dart as of above, and I tried to call the statelessWidget then. Now it says the "ref" parameter is required, what should I do? Here is a screenshot : https://gyazo.com/292ce0db8018a95ad8f5e17f660050c7 – lophix Oct 11 '22 at 18:29
  • What exactly you want to do with this new widget test, the ref parameter was a function to do , so if you want to make this work , you have two options , first is to remove the ref param from the second class , else you could prove a function that take int . – Ahmad Ellamey Oct 11 '22 at 23:05
  • The test widget should include a Row with a Text and the button (that redirects me to target.dart) next to it. I will have multiple widgets (stateless widgets like test) that I call in the Scaffold of Dashboard. – lophix Oct 12 '22 at 09:18
  • pass the same ref to the next widget like : Test(ref : ref) – Ahmad Ellamey Oct 12 '22 at 12:38