调用 Navigator.popUntil() 时出现黑屏

Posted

技术标签:

【中文标题】调用 Navigator.popUntil() 时出现黑屏【英文标题】:Black screen when calling Navigator.popUntil() 【发布时间】:2021-10-01 23:49:43 【问题描述】:

我正在制作一个 Flutter 应用程序,我可以在其中从主屏幕导航到其他页面。然后我想通过弹出导航器堆栈返回主屏幕。当我这样做时,我得到一个黑屏,我假设我弹出直到堆栈为空。但是我不明白我的错误在哪里。

page2.dart 中,如果我将Navigator.popUntil() 调用替换为两个对Navigator.pop(context) 的调用,它会成功弹回主屏幕。

为了演示我遇到的问题,我制作了一个具有此行为的独立应用程序。

ma​​in.dart

import 'package:flutter/cupertino.dart';
import 'package:test/router.dart' as router;
import 'package:flutter/widgets.dart';

void main() 
  runApp(const MyApp());


class MyApp extends StatefulWidget 
  const MyApp(Key? key) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  @override
  Widget build(BuildContext context) 
    return const CupertinoApp(
        title: 'Test',
        initialRoute: router.home,
        onGenerateRoute: router.generateRoute);
  

router.dart

import 'package:flutter/cupertino.dart';
import 'package:test/home.dart';
import 'package:test/page1.dart';
import 'package:test/page2.dart';
import 'package:flutter/widgets.dart';

const home = '/';
const page1 = '/page1';
const page2 = '/page2';

Route<dynamic> generateRoute(RouteSettings settings) 
  switch (settings.name) 
    case home:
      return CupertinoPageRoute(builder: (context) => const Home());
    case page1:
      return CupertinoPageRoute(builder: (context) => const Page1());
    case page2:
      return CupertinoPageRoute(builder: (context) => const Page2());
    default:
      print('Undefined view');
      return CupertinoPageRoute(
          builder: (context) => UndefinedView(
                name: settings.name ?? 'No Name',
              ));
  


class UndefinedView extends StatelessWidget 
  final String name;
  const UndefinedView(Key? key, required this.name) : super(key: key);
  @override
  Widget build(BuildContext context) 
    return CupertinoPageScaffold(
      child: Center(
        child: Text('Route for $name is not defined'),
      ),
    );
  

home.dart

import 'package:flutter/cupertino.dart';
import 'package:test/router.dart' as router;
import 'package:flutter/widgets.dart';

class Home extends StatefulWidget 
  const Home(Key? key) : super(key: key);

  @override
  _HomeState createState() => _HomeState();


class _HomeState extends State<Home> 
  @override
  Widget build(BuildContext context) 
    return CupertinoPageScaffold(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        CupertinoButton(
          child: const Text(
            'Go to page 1',
            style: TextStyle(color: Color.fromRGBO(0xFF, 0xFF, 0xFF, 1)),
          ),
          onPressed: () => Navigator.pushNamed(context, router.page1),
        ),
        Container(
          height: 50,
        )
      ],
    ));
  

page1.dart

import 'package:flutter/cupertino.dart';
import 'package:test/router.dart' as router;
import 'package:flutter/widgets.dart';

class Page1 extends StatefulWidget 
  const Page1(Key? key) : super(key: key);

  @override
  _Page1State createState() => _Page1State();


class _Page1State extends State<Page1> 
  @override
  Widget build(BuildContext context) 
    return CupertinoPageScaffold(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        CupertinoButton(
          child: const Text(
            'Go to Page 2',
            style: TextStyle(color: Color.fromRGBO(0xFF, 0xFF, 0xFF, 1)),
          ),
          onPressed: () => Navigator.pushNamed(context, router.page2),
        ),
        Container(
          height: 50,
        )
      ],
    ));
  

page2.dart

import 'package:flutter/cupertino.dart';
import 'package:test/router.dart' as router;
import 'package:flutter/widgets.dart';

class Page2 extends StatefulWidget 
  const Page2(Key? key) : super(key: key);

  @override
  _Page2State createState() => _Page2State();


class _Page2State extends State<Page2> 
  @override
  Widget build(BuildContext context) 
    return CupertinoPageScaffold(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        CupertinoButton(
          child: const Text(
            'Go home',
            style: TextStyle(color: Color.fromRGBO(0xFF, 0xFF, 0xFF, 1)),
          ),
          onPressed: () =>
              Navigator.popUntil(context, ModalRoute.withName(router.home)),
        ),
        Container(
          height: 50,
        )
      ],
    ));
  

【问题讨论】:

【参考方案1】:

在 generateRoute 中返回 CupertinoPageRoute 时,也尝试传递设置,即

return CupertinoPageRoute(
    settings: settings, 
    builder: (context) => const Home()
);

return CupertinoPageRoute(
    settings: const RouteSettings(name: home),
    builder: (context) => const Home()
);

我相信否则导航器不知道路线名称,这会导致 popUntil 弹出直到没有更多路线(因此黑屏)。

【讨论】:

这似乎有效。我还尝试将home: Home() 添加到_MyAppState 中的CupertinoApp(),它也解决了我的问题。我不完全确定它们为什么都有效以及有什么区别。

以上是关于调用 Navigator.popUntil() 时出现黑屏的主要内容,如果未能解决你的问题,请参考以下文章

C#线程调用方法时,怎么传参数过去

调用方法并将返回值分配给数组时,为啥C#在调用方法时使用数组引用?

当 AppX 调用 Service 然后调用 ServiceS 时,调用 Uid 是啥?

c++,类的对象作为形参时一定会调用复制构造函数吗?

从 .Net 线程调用时 COM 调用挂起

Moq:设置一个模拟方法在第一次调用时失败,在第二次调用时成功