Flutter WillPopScope для вложенной навигации - PullRequest
0 голосов
/ 09 июля 2020

У меня есть приложение Flutter с вложенным навигатором, и я хочу переопределить «onBackPressed», используя WillPopScope на моем вложенном экране.

Допустим, у меня есть MainScreen, PrimaryScreen и SecondaryScreen. PrimaryScreen - это вложенный навигатор, у него несколько экранов, например PrimaryOneScreen, PrimaryTwoScreen и PrimaryThreeScreen.

SecondaryScreen также является вложенным навигатором, как и PrimaryScreen, у него 3 экрана .

Вот иллюстрация того, чего я хочу достичь

MainScreen -> PrimaryScreen (PrimaryOneScreen -> PrimaryTwoScreen -> PrimaryThreeScreen)

Когда моя позиция на PrimaryTwoScreen, я хочу вернуться к PrimaryOneScreen с переопределением "onBackPressed" с помощью WillPopScope Widget. Но onWillPop никогда не вызывается, когда я нажимаю кнопку возврата, и мой экран go возвращается прямо к MainScreen.

Вот мои коды

MainScreen.dart

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MainApp(),
      onGenerateRoute: (settings){
        WidgetBuilder builder;
        switch(settings.name){
          case 'primary' :
            builder = (BuildContext _) => PrimaryScreen();
            break;
          case 'secondary' :
            builder = (BuildContext _) => SecondaryScreen();
            break;
          case 'main' :
            builder = (BuildContext _) => MainApp();
            break;
          default :
            throw Exception('Invalid route: ${settings.name}');
        }

        return MaterialPageRoute(
            builder: builder,
            settings: settings
        );
      },
    );
  }
}


class MainApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          FlatButton(
            onPressed: (){
              Navigator.pushNamed(context, 'primary');
            },
            child: Text('To Page Primary'),
          ),
          FlatButton(
            onPressed: (){
              Navigator.pushNamed(context, 'secondary');
            },
            child: Text('To Page Secondary'),
          )
        ],
      ),
    );
  }

}

PrimaryScreen.dart

class PrimaryScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Navigator(
        initialRoute: 'primary/pageone',
        onGenerateRoute: (RouteSettings settings){
          WidgetBuilder builder;
          switch(settings.name){
            case 'primary/pageone' :
              builder = (BuildContext _) => PrimaryOneScreen();
              break;
            case 'primary/pagetwo' :
              builder = (BuildContext _) => PrimaryTwoScreen();
              break;
            case 'primary/pagethree' :
              builder = (BuildContext _) => PrimaryThreeScreen();
              break;
            default :
              throw Exception('Invalid route: ${settings.name}');
          }

          return MaterialPageRoute(
              builder: builder,
              settings: settings
          );
        },
      );
  }

}

PrimaryOneScreen.dart

class PrimaryOneScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Primary Page'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
           FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagetwo');
              },
              child: Text('To Page Two'),
            ),
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagethree');
              },
              child: Text('To Page Three'),
            ),
          ],
        ),
      ),
    );
  }

}

PrimaryTwoScreen.dart

class PrimaryTwoScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: ()async{
        print('willPopScope');
        Navigator.of(context, rootNavigator: false).pop();
        return true;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Secondary Page'),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              FlatButton(
                onPressed: (){
                  Navigator.pushNamed(context, 'primary/pageone');
                },
                child: Text('To Page One'),
              ),
              FlatButton(
                onPressed: (){
                  Navigator.pushNamed(context, 'primary/pagethree');
                },
                child: Text('To Page Three'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

PrimaryThreeScreen.dart

class PrimaryThreeScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Primary Page'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pageone');
              },
              child: Text('To Page One'),
            ),
            FlatButton(
              onPressed: (){
                Navigator.pushNamed(context, 'primary/pagetwo');
              },
              child: Text('To Page Two'),
            )
          ],
        ),
      ),
    );
  }

}

РЕДАКТИРОВАТЬ Я добавил изображение, чтобы проиллюстрировать, чего я хочу достичь. введите описание изображения здесь

Как открывать только на вложенном навигаторе?

Спасибо!

1 Ответ

0 голосов
/ 09 июля 2020

Попробуйте по этой ссылке https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31

Проверить Пример использования: pushReplacementNamed описание тега

...