Flutter Navigator.pop(context) returning a black screen

DartFlutter

Dart Problem Overview


My Flutter Project structure is like this

Main() //Run App with MaterialApp and Routes
L HomePage() //Default route (/), with BottomNavigation
  L MoviesPage() //Default BottomNavigation Index and shows a list of movies form TMDB 
    L DetailsPage()
  L SeriesPage()
  L SupportPage()

After clicking on any movie it navigates forward to the DetailsPage() but when I call Navigator.pop from DetailsPage() it should go back to the previous screen but it doesn't.

The Navigator.canPop(context) return false But the hardware back button works absolutely fine, so how do I fix it?

main.dart

class BerryMain extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Inferno(
        {
          '/': (context, argumets) => HomePage(),
          '/detailspage': (context, arguments) => DetailsPage(arguments),
        },
      ).home(context),
    );
  }
}

homepage

class HomePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _HomePageState();
  }
}

class _HomePageState extends State<HomePage> {
  int _currentIndex = 0;
  final List<Widget> _childnav = [MoviesPage(), SeriesPage(), SupportPage()];

  void onTabPressed(...)

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('...'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {},
          )
        ],
      ),
      body: _childnav[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        onTap: onTabPressed,
        currentIndex: _currentIndex, //this property defines current active tab
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.movie), title: Text('Movies')),
          BottomNavigationBarItem(icon: Icon(Icons.tv), title: Text('Series')),
          BottomNavigationBarItem(icon: Icon(Icons.help), title: Text('Help'))
        ],
      ),
    );
  }
}

MoviesPage

//Inside ListView Builder
Virgil.pushNamed(context, '/detailspage', arguments: args);

DetailsPage

//Inside MaterialApp > Scaffold > SliverAppbar > BackButton
Navigator.pop(context)

I'm using Virgil but I don't think it is the problem.

Dart Solutions


Solution 1 - Dart

This can happen if your MoviesPage has another MaterialApp widget. Most of the time you want to use Scaffold as a top widget for a new page/screen, but if you accidentally use MaterialApp instead, nothing warns you.

What happens, is that MaterialApp creates a new Navigator, so if you switch from one page with MaterialApp to another, you now have two Navigators in the widget tree.

The call Navigator.of(context) looks for the closest Navigator, so it'll use the one, newly created in your MoviesPage. As the history of your route transitions is stored in a first Navigator, this one can't pop back – it has empty route history.

Hence, the black screen.

Long story short, to fix this, just use Scaffold as a top widget instead of MaterialApp in all nested screens.

Solution 2 - Dart

I had similar issues while poping back views, the way I fixed was instead of Navigator.of(context).pop(); I use Navigator.of(context).maybePop();.

No more black screens after that.

Solution 3 - Dart

Just add optionally param rootNavigator: true: Sample:

Navigator.of(context, rootNavigator: true).pop(context);

Edit: In some cases, this solution may not resolve your issue. Please make sure that there is only one MaterialApp widget in your app for all Pages.

Solution 4 - Dart

I resolve it using this code:

Navigator.pushReplacementNamed(context, '/route');

Solution 5 - Dart

Workaround is SystemNavigator.pop(); refer from this link

Solution 6 - Dart

I had a very similar problem and my solution was to pass BuildContext context from the created StatelessWidget to a global variable and pop that context from the global variable. So...

var globalContext; // Declare global variable to store context from StatelessWidget

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    globalContext = context; // globalContext receives context from StetelessWidget.

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        canvasColor: Colors.transparent,
        primarySwatch: Colors.blue,
      ),
      home: SecondScreenPage(title: 'SECOND SCREEN'),
    );
  }
}

class SecondScreenPage extends StatefulWidget {
  SecondScreenPage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _SecondScreenPageState createState() => _SecondScreenPageState();
}

class _SecondScreenPageState extends State<SecondScreenPage>() {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () => Navigator.pop(globalContext), // POPPING globalContext
        )
      ),
  ...
}

Now I don't get a black screen and I'm at my first page as if I had clicked on Android's back button. =)

I don't know if that is a good practice. If anyone knows a way to do that "more correctly", please feel free to answer.

Solution 7 - Dart

I also faced that problem and Still i was getting black screen after trying all of those previous answers.I do not have any idea about MaterialApp or Scafold reason because my application main.dart was only using MaterialApp, So Scafold solution did not work for me.Now what Solved for me.

POP BACK CODE

Navigator.of(context, rootNavigator: true).pop(context)

CODE THAT DID NOT WORK

 Navigator.pushReplacement(context,CupertinoPageRoute(fullscreenDialog: false,builder: (context) => ChildClass())),

CODE THAT WORKED

 Navigator.push(context,MaterialPageRoute(builder: (context) => ChildClass())

Solution 8 - Dart

Flutter App should have only 1 MaterialApp Why??? It is a core component that give access to all other elements

Technically thinking Material App contains App Title and a Home Screen widget

Here is my implementation

void main() { 
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return MaterialApp(
  title: 'First Flutter App',
  home: FirstActivity());
 }
}

class FirstActivity extends StatefulWidget {
   @override
   _FirstActivityState createState() {
   return _FirstActivityState();
   }
}

class _FirstActivityState extends State<FirstActivity> {
   @override
   Widget build(BuildContext context) {
   return Scaffold(
      appBar: AppBar(
      title: Text('First Activity'),
      ),
      body: Center(
      child: RaisedButton(
        child: Text('Move Forward'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => SecondActivity()),
          );
        }),
        ),
       );
     }
  }

  class SecondActivity extends StatefulWidget {
   @override
   _SecondActivityState createState() {
   return _SecondActivityState();
   }
}

class _SecondActivityState extends State<SecondActivity> {
   @override
   Widget build(BuildContext context) {
   return Scaffold(
      appBar: AppBar(
      title: Text('Second Activity'),
      ),
      body: Center(
      child: RaisedButton(
        child: Text('Move Back'),
        onPressed: () {              
           Navigator.pop(context);
        }),
        ),
       );
     }
  }

Solution 9 - Dart

Maybe in detail screen you are use MaterialApp as a main widget you need to just remove MaterialApp and diractly return Scaffold and maybe your problem will solve this is work for me.

Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
       body: Container(),
     ),
    );
  }

instead of

Widget build(BuildContext context) {
 return Scaffold(
   body: Container(),
 );
}

Solution 10 - Dart

to get rid of black screen, you can also use below method with as many pop() you want

Navigator.of(context)..pop()..pop();

Solution 11 - Dart

According to this Answer I figured it out a way.

You should pass the MoviesPage context to the DetailsPage. And that context should be called in Navigator.pop(context);

for Example: FIRST SCREEN

class FirstScreen extends StatelessWidget {
      final BuildContext context;
    
      FirstScreen(this.context);///here u have to call the build Context of FirstScreen
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
            home: FirstScreenScreen(this.context));
      }
    }
    
    class FirstScreenScreen extends StatefulWidget {
      final BuildContext context;
    
      FirstScreenScreen(this.context);/// and here also.
    
      @override
      _FirstScreenState createState() => _FirstScreenState();
    }
    
    class _FirstScreenState extends State<FirstScreenScreen> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
     body: Container(
            child: new RaisedButton(onPressed: (){

               navigateAndDisplaySelection(context);

            },
            child: new Text('Go to SecondPage'),
            ),
          ),
       );
     }
    }

SECOND SCREEN

 class SecondScreen extends StatelessWidget {
      final BuildContext context;
    
      SecondScreen(this.context);///here u have to call the build Context of FirstScreen
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
            home: SecondScreenScreen(this.context));
      }
    }
    
    class SecondScreenScreen extends StatefulWidget {
      final BuildContext context;
    
      SecondScreenScreen(this.context);/// and here also.
    
      @override
      _SecondScreenState createState() => _SecondScreenState();
    }
    
    class _SecondScreenState extends State<SecondScreenScreen> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
     body: Container(
            child: new RaisedButton(onPressed: (){
              Navigator.pop(widget.context);///this context is passed from firstScreen
            },
            child: new Text('Go Back'),
            ),
          ),
       );
     }
    }

Pass Data & Return
if you want pass data and return, add a constructor with parameter in SecondScreen and call setState in method Fisrtlike this:

 navigateAndDisplaySelection(
      BuildContext context) async {
    // Navigator.push returns a Future that will complete after we call
    // Navigator.pop on the Second Screen!
    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => new SecondScreen(context)),
    );
    setState(() {
     /// the passed value data will change here, when you change in second screen
    });
  }

Solution 12 - Dart

I would like to share my experience in this, as I had the same issue.

Basically, pop from empty screen stack is the major cause of this issue.

In my case, I was doing a periodic operation (reading some data from the camera) on scanner_screen (which was pushed to the stack by a button on my main_screen), when the camera finds a specific text, I call pop. The issue was that the camera was reading too fast, and thus I popped more than once, which means popping from an empty stack.

At first I though that popping is fast enough to call dispose on my scanner_screen to stop calling the periodic operation that keeps popping, but it was not. That is why I needed to make sure that periodic operation is stopped manually before popping from the screen stack.

I hope that may help somebody.

Solution 13 - Dart

Check your Navigator.push code

Navigator.of(context).pushReplacement(
            MaterialPageRoute(builder: (context) => Nextscreen()));

if you use .pushReplacement you cannot go back, it means you cannot use Navigator.pop(context).

otherwise, if you used

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

Kindly use this to get rid of the problem.

Navigator.of(context, rootNavigator: true).pop(context);

Solution 14 - Dart

  1. Import page where you want to go.

  2. Use Class of that Page-Ex.Appointment

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

3. Remove Push name from Navigator

Solution 15 - Dart

This behaviour also appears when the initialRoute is removed, something that can happen if you navigate to your first child by using:

Navigator.popAndPushNamed('...')

The solution is clearly simple tho, just use pushNamed instead.

Solution 16 - Dart

Before navigating to another screen use Navigator.pop(context).

Example:

Navigator.pop(context),
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(uilder: (_) => GoogleMapScreenRemasterd()),
(Route<dynamic> route) => false),

Solution 17 - Dart

this work for me, i think it's the better solution.

WidgetsBinding.instance.addPostFrameCallback((_) {
            Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => Menu()));
          }),

Solution 18 - Dart

i have same issue like returning same screen return black screen

    void main() async {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(home: Todo());
      }
    }
    
    class Todo extends StatefulWidget {
      const Todo({Key key}) : super(key: key);
    
    
      @override
      _TodoState createState() => _TodoState();
    }
    
    class _TodoState extends State<Todo> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
     body: RaisedButton(onPressed: (){
            //print(controler.text);
            //Navigator.push(context,MaterialPageRoute(builder: (context) => Todo("viral")));
            //_sendDataBack(context);
            Get.to(()=>Test());
    
          },child: Text("submit"),),
        ) ;
    
      }
    }
    
    other class
    
    class Test extends StatefulWidget {
      const Test({Key key}) : super(key: key);
    
      @override
      _TestState createState() => _TestState();
    }
    
    class _TestState extends State<Test> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: RaisedButton(onPressed: (){
            Get.to(()=>MyApp());
    
          },child: Text("submit"),),
        ) ;
    
      }
    }

and then i check my code and realize that i am passing wrong class i have to return class that have my widget tree so replace Myapp() to Todo() like below and that fix my issue

class Test extends StatefulWidget {
  const Test({Key key}) : super(key: key);

  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RaisedButton(onPressed: (){
        Get.to(()=>MyApp());

      },child: Text("submit"),),
    ) ;

  }
}

Solution 19 - Dart

Use Navigator.pushNamed instead of Navigator.pushReplacementNamed

Solution 20 - Dart

This is a common problem. These are just simple Issues. This happens when you push New screen and there also MaterialApp() widget.

Solution 21 - Dart

This solution may be help others to avoid black screens. As it helps me.

 if(Navigator.canPop(context)){
      Navigator.of(context).pop();
    }else{
      SystemNavigator.pop();
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNadeem SiddiqueView Question on Stackoverflow
Solution 1 - DartdivanView Answer on Stackoverflow
Solution 2 - DartRenan NeryView Answer on Stackoverflow
Solution 3 - DartHuy NguyenView Answer on Stackoverflow
Solution 4 - DartSunnyView Answer on Stackoverflow
Solution 5 - DartDivyanshu KumarView Answer on Stackoverflow
Solution 6 - DartGuilherme OliveiraView Answer on Stackoverflow
Solution 7 - DartEmonView Answer on Stackoverflow
Solution 8 - DartMuhammad Awais RashidView Answer on Stackoverflow
Solution 9 - Dartkunj kananiView Answer on Stackoverflow
Solution 10 - DartHimmet YelekinView Answer on Stackoverflow
Solution 11 - DartSoloWolf93View Answer on Stackoverflow
Solution 12 - DartMohammed NoureldinView Answer on Stackoverflow
Solution 13 - DartAnandh KrishnanView Answer on Stackoverflow
Solution 14 - DartAjay KambleView Answer on Stackoverflow
Solution 15 - DarteMarineView Answer on Stackoverflow
Solution 16 - DartgsmView Answer on Stackoverflow
Solution 17 - DartFatima ELKADDOURIView Answer on Stackoverflow
Solution 18 - Dartparmar viralView Answer on Stackoverflow
Solution 19 - DartchipmunkView Answer on Stackoverflow
Solution 20 - DartMusfiq ShantaView Answer on Stackoverflow
Solution 21 - DartUmairView Answer on Stackoverflow