flutterproviderdart-pubbottom-navigation-bar

How to Hide bottom navigation bar using provider flutter


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