Muhammad Tayyab
Muhammad Tayyab

Reputation: 51

How to close drawer on WillPop from the dashboard in flutter?

I want to go back to the home screen from the side drawer when user clicks on mobile back button. Please give me some suggestions or solutions about that.

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

But I want it when side drawer is open and user press back it will be closed but when the side drawer is not open and user presses back then the dialog will be shown.

Kindly let me know what changes I need 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;
  }
}

Upvotes: 1

Views: 588

Answers (1)

Omodolapo
Omodolapo

Reputation: 56

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...

Upvotes: 1

Related Questions