How to Hide bottom navigation bar using provider flutter

Issue

I am working on a social media app which contains a home screen with bottom navbar and 5 pages .
Although i am able to change the bool value to show or hide navbar under provider but the changes are not reflecting in widget .

main.dart –

MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => 
ScrollProvider(),
        ),
      ],
child : MyApp()

My provider class –

     class ScrollProvider with ChangeNotifier{
  bool isVisible = true;

  void show() {

      isVisible = true;
      print("in Provider $isVisible");

      notifyListeners();
  }

  void hide() {

      isVisible = false;
      print("in Provider $isVisible");

      notifyListeners();

  }
}

Page which has the value scrollcontroller

 ScrollController _scrollController =
      ScrollController(); 

      _scrollController.addListener(() {
     
     final direction =
          _scrollController.position.userScrollDirection;

      if (direction == ScrollDirection.forward) {
        ScrollProvider().show();
        }
      if (direction == ScrollDirection.reverse) {

          ScrollProvider().hide();
      }
    });

And my homescreen which which has body and navbar contains this code

‘’’

bottomNavigationBar: Consumer<BottomBarVisibilityProvider>(
    builder: (context, bottomBarVisibilityProvider, child) =>
        AnimatedContainer(
      duration: const Duration(milliseconds: 200),
      child: bottomBarVisibilityProvider.isVisible
          ? Wrap(
              children: const [BottomBar()],
            )
          : Wrap(),
    ),
  ),

I have initialised the provider inside main.dart

Can someone tell me why its not working .. and what should i do

here is the full code of homepage

class _HomeState extends State<Home> {
 

  List<Widget> _pages ;
  @override
  void initState() {
    super.initState();
   
    _pages = [
      MemeTabView(scrollController: scrollToHide),
      TempTab(),
      null,
      NotificationScreen(),
      ProfileScreen(uid: FirebaseAuth.instance.currentUser.uid,showAppBar: false),
    ];
  }




  @override
  Widget build(BuildContext context) {
    if (widget.selectedIndex == null) {
      widget.selectedIndex = 0;
    }

    return
      Scaffold(
      appBar: AppBar(
        title: brandName(),
      ),
      extendBody: true,
      bottomNavigationBar:
            Consumer<ScrollProvider>(
              builder: (_,scrollProvider,__){
               
                return Container(
                  child: scrollProvider.isVisible == true
                      ?
                      bottomNav()


                      : Container(),
                );
              },
            ),


      drawer: MyDrawer(),
      body:PageView(
        controller: _pageController,
       
        physics: NeverScrollableScrollPhysics(),
        children: _pages,
      ),
    );
  }

Solution

You need to read provider like

context.read<BottomBarVisibilityProvider>();
void main() {
  runApp(
    /// Providers are above [MyApp] instead of inside it, so that tests
    /// can use [MyApp] while mocking the providers
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => BottomBarVisibilityProvider()),
      ],
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.\
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const SCCR(),
    );
  }
}

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

  @override
  State<SCCR> createState() => _SCCRState();
}

class _SCCRState extends State<SCCR> {
//just for test purpose
  late final bottomBarVisibilityProvider =
          context.read<BottomBarVisibilityProvider>();
  late final ScrollController scrollController = ScrollController()
    ..addListener(() {
     
      final direction = scrollController.position.userScrollDirection;

      if (direction == ScrollDirection.forward) {
        if (!bottomBarVisibilityProvider.isVisible) {
          bottomBarVisibilityProvider.show();
        }
      } else if (direction == ScrollDirection.reverse) {
        if (bottomBarVisibilityProvider.isVisible) {
          bottomBarVisibilityProvider.hide();
        }
      }
    });
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        controller: scrollController,
        child: Container(
          height: 3333,
        ),
      ),
      bottomNavigationBar: Consumer<BottomBarVisibilityProvider>(
        builder: (context, bottomBarVisibilityProvider, child) =>
            AnimatedContainer(
          duration: const Duration(milliseconds: 200),
          child: bottomBarVisibilityProvider.isVisible
              ? Wrap(
                  children: [
                    Container(
                      height: 100,
                      color: Colors.red,
                      width: 100,
                    )
                  ],
                )
              : null,
        ),
      ),
    );
  }
}

I will suggest to follow documentation

Answered By – Yeasin Sheikh

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

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