Home > Software design >  How to close drawer on WillPop from the dashboard in flutter?
How to close drawer on WillPop from the dashboard in flutter?

Time:09-01

I want to go back on home screen from side drawer, when user click on mobile back button, please give me some suggestions or solution about that.

In side drawer created by me, when user clicks on any link, user goes to that screen and drawer closes as well, no issues with that, also when user opens side drawer and press back key, drawer not closes, and show dialog box of exit app or not.

But I want when side drawer is open and user press back it will be close but when side drawer is not open and user press back then dialog will be show.

Kindly let me know what changes I have to do to implement this behavior.

class _DashboardState extends State<Dashboard> {
  String _currentPage = 'HomePage';

  @override
  void initState() {
    super.initState();
    _currentPage = widget.initialPage; //_currentPage;
  }

  @override
  Widget build(BuildContext context) {
    final tabs = {
      'HomeScreen': const HomeScreen(),
      'Search': const SearchScreen(),
      'Orders': const MyOrdersScreen(),
      'Profile': const ProfileScreen(),
      //'Personal_Profile' : PersonalProfileWidget(),
    };
    final currentIndex = tabs.keys.toList().indexOf(_currentPage);
    return WillPopScope(
      onWillPop: _onWillPop,
      child: Scaffold(
        drawer: const SideDrawer(),
        body: tabs[_currentPage],
        bottomNavigationBar: Theme(
          data: Theme.of(context).copyWith(
              primaryColor: AppColors.appThemeColor,
              disabledColor: AppColors.lightBlueGrayColor
          ),
          child: BottomNavigationBar(
            currentIndex: currentIndex,
            onTap: (i) => setState(() => _currentPage = tabs.keys.toList()[i]),
            backgroundColor: Colors.white,
            selectedItemColor: AppColors.appThemeColor,
            //unselectedItemColor: Color(0x8A000000),
            // showSelectedLabels: true,
            // showUnselectedLabels: flse,
            type: BottomNavigationBarType.fixed,
            items: <BottomNavigationBarItem>[
              //For Home Screen
              BottomNavigationBarItem(
                  icon: Image.asset("images/ic_nav_inactive_home.png"),
                  label: AppLocalizations.of(context)!.home,
                  activeIcon: Image.asset("images/ic_nav_home.png")
              ),

              //For Search Screen
              BottomNavigationBarItem(
                  icon: Image.asset("images/ic_nav_search.png"),
                  label:   AppLocalizations.of(context)!.search,
                  activeIcon: Image.asset("images/ic_nav_active_search.png")
              ),

              //For Orders Screen
              BottomNavigationBarItem(
                  icon: Image.asset("images/ic_nav_offers.png"),
                  label: "Orders",
                  activeIcon: Image.asset("images/ic_nav_active_offers.png")
              ),

              //For My Profile Screen
              BottomNavigationBarItem(
                  icon: Image.asset("images/ic_nav_profile.png"),
                  label: AppLocalizations.of(context)!.profile,
                  activeIcon: Image.asset("images/ic_nav_active_profile.png"))
            ],
          ),
        ),
      ),
    );
  }
  Future<bool> _onWillPop() async {
    return (await showDialog(
      context: context,
      builder: (context) => AlertDialog(
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(12.0))),
        //contentPadding: const EdgeInsets.only(top: 10.0),
        backgroundColor: AppColors.whiteShadeColor,
        content: const Text(
            "Are you sure?\nDo you want to exit an App",
            style: TextStyle(
                fontWeight: FontWeight.bold,
                color: AppColors.blackColor
            )
        ),
        actions: <Widget>[
          TextButton(
            child: const Text(
              "No",
              style: TextStyle(
                  color: AppColors.darkBlueColor,
                  fontWeight: FontWeight.bold,
                  fontSize: 14
              ),
            ),
            onPressed: () {
               Navigator.of(context).pop(false);
            },
          ),
          TextButton(
            child: const Text(
              "Yes",
              style: TextStyle(
                  color: AppColors.redColor,
                  fontWeight: FontWeight.bold,
                  fontSize: 14
              ),
            ),
            onPressed: () {
              Navigator.of(context).pop(true);
            },
          )
        ],
      )
    )) ?? false;
  }
}

CodePudding user response:

i think the first thing you should do in your onWillPop method is to check if your drawer is open. If it is open, the the back button should close the drawer, if it isn't open it shows the dialog. So you should have something like this...

  Future<bool> _onWillPop() async {
     if(scaffoldKey.currentState!.isDrawerOpen){
                 scaffoldKey.currentState!.closeDrawer();
        return false;
              }
    else{
    return ( await showDialog(...
    }

Just in case you're confused about where I got the scaffoldKey...It is only right that the scaffold of the screens that house the drawer should have a GlobalKey assigned to it. With this you're able to open, close, or check the state of your drawer.

You can declare the variable in your private _DashboardState class like this...

GlobalKey scaffoldKey = GlobalKey();

And in your Scaffold, the scaffoldKey should be assigned to the key. I hope this helps...

  • Related