Flutter Navigator.popUntil () с ModalRoute.withName () не работает в режиме профиля и выпуска

У меня есть функция, которая переходит на новую страницу с настройками маршрута

void pushWithSettings(
    {@required BuildContext context, @required Widget newPage}) {
  Navigator.push(
      context,
      MaterialPageRoute(
          settings: RouteSettings(
            name: newPage.toString(),
          ),
          builder: (_) => newPage));
}

и я перехожу к определенной странице, используя

Navigator.popUntil(context, ModalRoute.withName(Page().toString));

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

Пример контекста

import 'package:flutter/material.dart';
import 'package:flutter_app/main.dart';

class FirstPage extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Center(child: Text("First Page"),),
        RaisedButton(
          onPressed: (){
            pushWithSettings(context: context, newPage: SecondPage());
          },
          child: Text("Navigate to second", style: TextStyle(inherit: false)),
        )
      ],
    );
  }
}

class SecondPage extends StatelessWidget {
  
@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      Center(child: Text("Second Page"),),
      RaisedButton(
        onPressed: (){
          pushWithSettings(context: context, newPage: ThirdPage());
        },
        child: Text("Navigate to third", style: TextStyle(inherit: false)),
      )
    ],
  );
}
}

class ThirdPage extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Center(child: Text("Third Page"),),
        RaisedButton(
          onPressed: (){
            Navigator.popUntil(context, ModalRoute.withName(FirstPage().toString()));
          },
          child: Text("Navigate to first", style: TextStyle(inherit: false),),
        )
      ],
    );
  }
}

В режиме отладки нажатие кнопки на третьей странице приводит к переходу на первую страницу, но в режиме профиля и выпуска нажатие кнопки ничего не делает. Я сейчас использую flutter 1.17.4 на стабильном канале


person faithomotoso    schedule 12.07.2020    source источник
comment
Возможно, Page (). ToString () не возвращает то же самое при отладке и выпуске. Не могли бы вы попробовать добавить еще одну строку в качестве имени маршрута? Попробуйте использовать простую строку, чтобы увидеть, работает ли это.   -  person jamesblasco    schedule 13.07.2020


Ответы (2)


Я пробовал ваш код, FirstPage().toString() в режиме профиля возвращает «Widget», а при отладке возвращает «FirstPage».

Я бы добавил миксин, содержащий строку routeName, которую вы можете использовать.

Также помните, что по крайней мере для Интернета рекомендуется, чтобы ваш первоначальный маршрут был с '/'.


void pushWithSettings(
    {@required BuildContext context, @required NamedRoute newPage}) {
  Navigator.push(
      context,
      MaterialPageRoute(
          settings: RouteSettings(
            name: newPage.routeName,
          ),
          builder: (_) => newPage));
}

mixin NamedRoute implements Widget {
  String get routeName;
}


class ThirdPage extends StatelessWidget with NamedRoute {
  @override
  String get routeName => '/third_page';

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Center(
          child: Text("Third Page"),
        ),
        RaisedButton(
          onPressed: () {
            Navigator.popUntil(context, ModalRoute.withName(FirstPage().routeName));
          },
          child: Text(
            "Navigate to first",
            style: TextStyle(inherit: false),
          ),
        )
      ],
    );
  }
}

Проверьте кодовое слово https://codepen.io/jamesblasco/pen/QWyBQOm.

person jamesblasco    schedule 13.07.2020
comment
Пробовал миксин. Все еще не сработало. Вы правы насчет смены названия на Widget. По какой-то причине я не могу запускать инструменты разработчика в режиме профиля. - person faithomotoso; 13.07.2020
comment
Миксин сработал. Я допустил ошибку при внедрении. Спасибо. Я пробовал использовать runtimeType, и это тоже сработало, поэтому name: newPage.routeName стало name: newPage.runtimeType - person faithomotoso; 14.07.2020
comment
Рад, что ты заставил это работать. Просто обратите внимание, что flutter рекомендует использовать для ваших маршрутов именование, подобное пути. - person jamesblasco; 16.07.2020
comment
Мобильные приложения часто управляют большим количеством маршрутов, и часто проще называть их по имени. В именах маршрутов по соглашению используется структура, подобная пути (например, '/ a / b / c'). Маршрут домашней страницы приложения по умолчанию называется «/». api.flutter.dev/flutter/widgets/Navigator-class.html - person jamesblasco; 16.07.2020

Первый ответ работает, но, чтобы не добавлять миксины на все доступные мне страницы, я вместо этого использовал runtimeType, поэтому

settings: RouteSettings(
            name: newPage.toString(),
          ),

стал

settings: RouteSettings(
            name: newPage.runtimeType.toString(),
          ),
person faithomotoso    schedule 14.07.2020
comment
Это должен быть правильный ответ. - person Benjamin; 22.04.2021