Черный экран при вызове навигатора.popUntil()

#flutter #dart

Вопрос:

Я создаю приложение Flutter, в котором я перемещаюсь с главного экрана на другие страницы. Затем я хочу вернуться на главный экран, открыв стек навигатора. Когда я это делаю, я получаю черный экран, и я предполагаю, что я выскакиваю, пока стек не опустеет. Однако я не понимаю, в чем моя ошибка.

В page2.dart случае , если я заменю Navigator.popUntil() вызов двумя вызовами Navigator.pop(context) друг за другом, он успешно вернется на главный экран.

Чтобы продемонстрировать проблему, я создал отдельное приложение с таким поведением.

главная.дротик

 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);
  }
}
 

маршрутизатор.дротик

 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,
        )
      ],
    ));
  }
}
 

страница 2.дротик

 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:

При возврате CupertinoPageRoute внутри generateRoute попробуйте также передать настройки, т. Е.

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

или

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

Я считаю, что в противном случае Навигатор не знает названий маршрутов, что приводит к появлению popUntil до тех пор, пока маршрутов больше не останется (таким образом, черный экран).

Комментарии:

1. Кажется, это работает. Я также попытался добавить home: Home() в CupertinoApp() in _MyAppState , и это также решило мою проблему. Я не совсем понимаю, почему они оба работают и в чем разница.