1

I have three screens in the example app - HomeScreen, ScreenOne and ScreenTwo. Navigation is implemented using a custom Drawer widget. Tapping on the phone's back button goes back to the home screen instead of the previous screen in the memory stack. I tried resolving the issue by using a WillPopScope widget in the home property of the ScreenTwo widget's MaterialApp Widget but onWillPop does not get called for the ScreenTwo widget. Instead it gets called only when it is included in the HomeScreen widget. I have no idea why this is happening. I can also not understand why the using the phone's back button does not go back to the previous screen in the memory stack. How to solve this problem?

Here is my code:

home_screen.dart file

import 'package:flutter/material.dart';
import 'drawer_widget.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: WillPopScope(
        onWillPop: () => Future.value(false),
        child: SafeArea(
          child: Scaffold(
            drawer: DrawerWidget(),
            appBar: AppBar(
              title: Text("WillPopScope Demo"),
              leading: Builder(
                builder: (context) => IconButton(
                  icon: Icon(Icons.menu),
                  onPressed: () => Scaffold.of(context).openDrawer(),
                ),
              ),
            ),
            body: Container(
              child: Center(
                child: Text("Home Screen"),
              ),
            ),
          ),
        ),
      )
    );
  }
}

screen_one.dart file:

import 'package:flutter/material.dart';
import 'drawer_widget.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: WillPopScope(
          onWillPop: () => Future.value(false),
          child: SafeArea(
            child: Scaffold(
              drawer: DrawerWidget(),
              appBar: AppBar(
                title: Text("WillPop Scope Demo"),
                leading: Builder(
                  builder: (context) => IconButton(
                    icon: Icon(Icons.menu),
                    onPressed: () => Scaffold.of(context).openDrawer(),
                  ),
                ),
              ),
              body: Container(
                child: Center(
                  child: Text("Screen One"),
                ),
              ),
            ),
          ),
        )
    );
  }
}

screen_two.dart file:

import 'package:flutter/material.dart';
import 'drawer_widget.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: WillPopScope(
          onWillPop: () => Future.value(false),
          child: SafeArea(
            child: Scaffold(
              drawer: DrawerWidget(),
              appBar: AppBar(
                title: Text("WillPop Scope Demo"),
                leading: Builder(
                  builder: (context) => IconButton(
                    icon: Icon(Icons.menu),
                    onPressed: () => Scaffold.of(context).openDrawer(),
                  ),
                ),
              ),
              body: Container(
                child: Center(
                  child: Text("Screen Two"),
                ),
              ),
            ),
          ),
        )
    );
  }
}

drawer_widget.dart file

import 'package:flutter/material.dart';
import 'home_screen.dart';
import 'screen_one.dart';
import 'screen_two.dart';

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

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 275,
      color: Colors.grey[900],
      child: ListView(
        children: [
          ListTile(
            title: Text("Home Screen", style: TextStyle(color: Colors.white, fontSize: 18)),
            onTap: () {
              Navigator.pop(context);
              Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen()));
            },
          ),
          ListTile(
            title: Text("Screen One", style: TextStyle(color: Colors.white, fontSize: 18)),
            onTap: () {
              Navigator.pop(context);
              Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenOne()));
            },
          ),
          ListTile(
            title: Text("Screen Two", style: TextStyle(color: Colors.white, fontSize: 18)),
            onTap: () {
              Navigator.pop(context);
              Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenTwo()));
            },
          )
        ],
      ),
    );
  }
}
flutternoob
  • 296
  • 5
  • 8

3 Answers3

0

Try again by changing this code:

onTap: () {
              Navigator.pop(context);
              Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenTwo()));
            },

to

onTap: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenTwo()));
           },
Aashar Wahla
  • 2,785
  • 1
  • 13
  • 19
  • I had added ```Navigator.pop(context)``` to pop the drawer when I navigate to the new screen. Even when I remove this line from the code, the problem does not go away. Instead, it now shows the drawer on the ```HomeScreen``` widget, no matter which screen I navigate from. – flutternoob May 31 '21 at 16:40
0

I solved the problem by referring to this post. I created a MyApp Stateless Widget and passed the HomeScreen widget to this MyApp widget. I removed the extra MaterialApp widgets from the ScreenOne and ScreenTwo widgets. I kept everything else the same in the code. WillPopScope worked as did using the device's back button after implementing this change in the code. Strangely, this worked, considering it wasn't a problem with some of my other apps. Unrelated, but I had not upgraded the Flutter plugin in Android Studio after last upgrading the Flutter SDK. I upgraded the Flutter plugin as well.

flutternoob
  • 296
  • 5
  • 8
0

From ... WillPopScope( onWillPop: () => Future.value(false), .... );

To..... WillPopScope( onWillPop: () async => false, ..... );

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 07 '22 at 06:55