how to handle the back button of andriod in flutter

4.3k Views Asked by At

I am working on an flutter application where it has more than 5 screens, I want to handle the back button of android, for example, when I logged in on app, it display the dashboard screen, so when I move to profile and then move to history screen, and when I click on back button on history screen it should navigate to profile screen, because the last screen I visited before history screen is profile, but it display the first screen which login screen.

I found the solution which works like when I click on back button it close the app.

Update:

My screens are navigating from drawer and from bottom navigation, there is only login screen where i use login button and calling dashboard screen onpressed function, other than this there is no button on any screen which navigate to other screens. here is the code for drawer and bottom navigation.

this is line of code i am using on login button

 Navigator.push(
              context, new MaterialPageRoute(builder: (context) => Employee()));

drawer and bottom navigation code: Code:

class Employee extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: new ThemeData(
        primaryColor: Colors.blue
      ),
      home: EmployeeNavigation(),
    );
  }
}
  int _selectedTab = 0;
  final _pageOptions = [
    EmployeeDashboard(),
    location(),
    Profile()
  ];

  String getname="";
  String getemail="";
  String getdesignation="";
  String getaccesstoken="";   
  String getdate;
  String getTime;

// ignore: must_be_immutable
class EmployeeNavigation extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return EmployeeNavigationState();
  }
}
class EmployeeNavigationState extends State<EmployeeNavigation> {
  
  var email;
  var designation;
  var date;
  bool valuefirst = false;
  String backtext="";

  @override
  Widget build(BuildContext context) {
   //i used this too but it doesn't work.
    return WillPopScope(
      onWillPop: () async {
        if (_selectedTab == 0) {
          return true;
        }
        setState(() {
          _selectedTab = 0;
        });
        return false;
      },
      
    child:Scaffold(    
    drawer:Emp_DrawerCode(),
    body:  _pageOptions[_selectedTab], 
    bottomNavigationBar: BottomNavigationBar(
     backgroundColor: Colors.blue[50],
    type: BottomNavigationBarType.fixed,
    currentIndex: _selectedTab,
    onTap: (value) {
      print(value);
      setState(() {
        _selectedTab = value;
      });
    },
    items: [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
      BottomNavigationBarItem(icon: Icon(Icons.location_on), label: "Location"),
      BottomNavigationBarItem(
        icon: Icon(Icons.person),
        label: "Profile",
      ),
    ],
  )));
  
}
}



class Emp_DrawerCode extends StatefulWidget {
  @override
  _Emp_DrawerCodeState createState() => _Emp_DrawerCodeState();
}

class _Emp_DrawerCodeState extends State<Emp_DrawerCode> {

  SharedPreferences myPrefs;
  name() async{
     myPrefs=await SharedPreferences.getInstance();
    setState(() {
          getname=myPrefs.getString('name');
          getemail=myPrefs.getString('email');
          getdesignation=myPrefs.getString('designation');
   
        });
    
  }
  void initState(){
    name();
  }

  @override
  Widget build(BuildContext context) {
    return new Drawer(
      child: new ListView(
          padding: const EdgeInsets.all(0.0),
          children: <Widget>[
            
            new UserAccountsDrawerHeader(
                accountName: new Text(getname),
                accountEmail: new Text(getemail),
                currentAccountPicture: new CircleAvatar(
                  backgroundColor:
                  Theme.of(context).platform == TargetPlatform.android
                      ? Colors.white
                      : Colors.blue,
              child: Text(
                getname[0][0],
                style: TextStyle(fontSize: 40.0),
              ),
            ),
          ),
          new ListTile(
              title: new Text('Home'),
              leading: Icon(Icons.dashboard,color:Colors.grey),
              onTap: (){
                Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(
                    builder: (context)=> EmployeeNavigation()
                    )
                  );
              },
            ),
            new ListTile(
              title: new Text('Request for leave'),
              leading: Icon(Icons.request_page,color:Colors.grey),
              onTap: (){
                Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(
                    builder: (context)=>RequestForLeave()
                    )
                  );
              },
            ),
            new ExpansionTile(
              title: new Text('History'),
              children: <Widget>[
                ListTile(
                   title:new Text("My Attendance"),
                  leading: Icon(Icons.assessment_outlined ,color:Colors.grey),
                  onTap: (){
                Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(
                    builder: (context)=>new MyAttendance()
                    )
                  );
              },
                 
                ),
                ListTile(
                   title:new Text("Leaves"),
                  leading: Icon(Icons.assessment_outlined,color:Colors.grey ),
                  onTap: (){
                Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(
                    builder: (context)=>new LeaveHistory()
                    )
                  );
              },
                 
                ),
              ],
              leading: Icon(Icons.history,),
            
            ),
           
            new ListTile(
              title: new Text('Log out'),
              leading: Icon(Icons.logout,color:Colors.grey),
              onTap: (){
                myPrefs.setBool('login', true);
                Navigator.pop(context);
                  Navigator.push(context, new MaterialPageRoute(
                    builder: (context)=>
                    
                    Login()
                    )
                  );
              },
            ),
            
            ],
            
        ),
        

      
    );
  }
}

kindly please help how to do this.

3

There are 3 best solutions below

6
Z_Z On

I am using navigator.push method and it is acting as you want.

appBar: AppBar(
  leading: IconButton(
    icon: Icon(Icons.arrow_back, color: Colors.blue),
    onPressed: () => Navigator.of(context).pop(),
  ), 
  title: Text("Sample"),
  centerTitle: true,
),

I wish it solve your problem.

1
ldev On

You need to first clarify your question a bit more.

Are using page view/ are you talking about a scenario where all are separately navigable screens or some different scenario ?

I am considering it as the second scenario when all are separately navigable screens.

In that case, every time user navigates to next screen you must use Navigator.pushNamed() / Navigator.push() as for now I think you are using Navigator.pushReplacement() which is causing this issue probably.

Navigator is nothing but a class aware of the stack of screens in the memory and so are the functions it provides us with. A simple push would mean pushing over the last pushed screen whereas pushing a replacement would replace the last pushed screen ultimately preventing you from navigating to the last pushed screen. Exactly like how it would work for a stack data structure.

1
awh On

Firstly Wrap your Scaffold with WillPopScope

    return WillPopScope(
      onWillPop: _onBackPressed,
      child : Scaffold());

And then you can call the Function that handles the back press.

// Back Button Android Behaviour
      Future<bool> _onBackPressed() async {
        final shouldPop = await showDialog(
            context: context,
            builder: (context) => AlertDialog(
                  title: Text(
                    "Are you sure you want to leave this page?",
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 25.0,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                  actions: <Widget>[
                    SizedBox(width: 16),
                    InkWell(
                      onTap: () {
                        Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(
                            builder: (BuildContext context) => HomeScreen(), // Destination
                          ),
                          (route) => false,
                        );
                      },
                      child: Container(
                        padding: EdgeInsets.all(8.0),
                        child: Text(
                          "LEAVE",
                          style: TextStyle(
                            color: Colors.red,
                            fontSize: 20.0,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                    ),
                    SizedBox(width: 8.0),
                    InkWell(
                      onTap: () => Navigator.of(context).pop(false),
                      child: Container(
                        padding: EdgeInsets.all(8.0),
                        child: Text(
                          "DO NOT LEAVE",
                          style: TextStyle(
                            color: Colors.black,
                            fontSize: 20.0,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                    ),
                  ],
                ));
        return shouldPop ?? false;
      }