Flutter Navigator.pop(context)返回黑屏

Nad*_*que 10 dart flutter

我的Flutter Project结构是这样的

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()
Run Code Online (Sandbox Code Playgroud)

单击任何电影后,它将向前导航到DetailsPage(),但是当我从DetailsPage()调用Navigator.pop时,它应该返回上一个屏幕,但没有。

Navigator.canPop(context)返回false,但是硬件后退按钮工作正常,那么如何解决呢?

主镖

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),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

主页

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'))
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

电影页面

//Inside ListView Builder
Virgil.pushNamed(context, '/detailspage', arguments: args);
Run Code Online (Sandbox Code Playgroud)

详细页面

//Inside MaterialApp > Scaffold > SliverAppbar > BackButton
Navigator.pop(context)
Run Code Online (Sandbox Code Playgroud)

我正在使用Virgil,但我不认为这是问题所在。

div*_*van 29

如果您MoviesPage有另一个MaterialApp小部件,可能会发生这种情况。大多数情况下,您想Scaffold用作新页面/屏幕的顶部小部件,但是如果您不小心使用它MaterialApp,则不会发出任何警告。

结果是,这将MaterialApp创建一个new Navigator,因此,如果您从一个页面切换MaterialApp到另一页面,则现在在小部件树中有两个导航器。

该呼叫会Navigator.of(context)寻找最接近的 Navigator,因此它将使用在中新创建的Navigator MoviesPage。由于您的路线转换历史记录存储在第一个导航器中,因此该导航器无法弹出-它具有空的路线历史记录。

因此,黑屏。

长话短说,要解决此问题,只需将其Scaffold用作顶部小部件,而不要MaterialApp在所有嵌套屏幕中使用。

  • 我只在main.dart中使用MaterialApp,然后也正在面对黑屏,同时使用Navigator.push(context,MaterialPageRoute(builder:(context){return VisitorsIN();}));` (3认同)
  • 不工作!我只有一个“MaterialApp”。 (3认同)
  • 这应该接受答案 (2认同)

Ren*_*ery 15

我在弹出视图时遇到了类似的问题,我修复的方法是而不是Navigator.of(context).pop();使用Navigator.of(context).maybePop();.

之后就没有黑屏了。

  • MaybePop() 也会在您从第一个屏幕显示警报对话框时失败。它只检查它是否可以弹出。它将始终返回 yes,并在您已经显示警报对话框时弹出一个小部件。 (2认同)

Huy*_*yen 13

只需添加可选参数rootNavigator: true:示例:

Navigator.of(context, rootNavigator: true).pop(context);
Run Code Online (Sandbox Code Playgroud)

编辑:在某些情况下,此解决方案可能无法解决您的问题。请确保MaterialApp您的应用中所有页面都只有一个小部件。


Emo*_*mon 9

我也遇到了这个问题,在尝试了所有以前的答案后,我仍然遇到黑屏。我对 MaterialApp 或 Scafold 的原因没有任何想法,因为我的应用程序 main.dart 仅使用 MaterialApp,所以 Scafold 解决方案对我不起作用.现在为我解决了什么。

弹出返回代码

Navigator.of(context, rootNavigator: true).pop(context)
Run Code Online (Sandbox Code Playgroud)

不起作用的代码

 Navigator.pushReplacement(context,CupertinoPageRoute(fullscreenDialog: false,builder: (context) => ChildClass())),
Run Code Online (Sandbox Code Playgroud)

有效的代码

 Navigator.push(context,MaterialPageRoute(builder: (context) => ChildClass())
Run Code Online (Sandbox Code Playgroud)


Gui*_*ira 6

我有一个非常相似的问题,我的解决方案是将 BuildContext上下文从创建的 StatelessWidget 传递到全局变量,然后从全局变量中弹出该上下文。所以...

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
        )
      ),
  ...
}
Run Code Online (Sandbox Code Playgroud)

现在我没有黑屏,而且我在我的第一页,就好像我点击了 Android 的后退按钮一样。=)

我不知道这是否是一个好习惯。如果有人知道“更正确”的方法,请随时回答。


Div*_*mar 6

解决方法 SystemNavigator.pop(); 参考此链接

  • 这实际上会退出应用程序。不是OP正在寻找的东西。 (4认同)

Sun*_*nny 5

我使用以下代码解决它:

Navigator.pushReplacementNamed(context, '/route')
Run Code Online (Sandbox Code Playgroud)


Ana*_*nan 5

检查你的Navigator.push代码

Navigator.of(context).pushReplacement(
            MaterialPageRoute(builder: (context) => Nextscreen()));
Run Code Online (Sandbox Code Playgroud)

如果您使用了.pushReplacement则无法返回,则意味着您无法使用Navigator.pop(context)

否则,如果你使用

Navigator.push(context, MaterialPageRoute(builder: (context) => ListScreen(),),);
Run Code Online (Sandbox Code Playgroud)

请使用它来解决这个问题。

Navigator.of(context, rootNavigator: true).pop(context);
Run Code Online (Sandbox Code Playgroud)