2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutter : Navigator2.0 river_pod で画面遷移を実現する

Posted at

先に実装のせておきます

どなたかの参考になれば幸いです。
こうした方が良いなどあればご教示願います!

custom_roter_delegate.dart
enum PageName {
  hogePage,
  fugaPage,
  fooPage
}

// これをローカルに宣言してしまうと画面遷移アニメーションが表示されないようになってしまいます。
final GlobalKey<NavigatorState> _nestedNavigatorKey = GlobalKey<NavigatorState>();

class CustomRouterDelegate extends RouterDelegate<void>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin {
  CustomRouterDelegate(this.ref);

  final WidgetRef ref;

  @override
  GlobalKey<NavigatorState>? get navigatorKey => _nestedNavigatorKey;

  @override
  Widget build(BuildContext context) {
    final fooPageTitle = ref.watch(fooPageTitleProvider);

    return Navigator(
      key: _nestedNavigatorKey,
      pages: [
        const MaterialPage(
          arguments: PageName.hogePage,
          child: HogePage(),
        ),
        if (ref.watch(showFugaPageProvider))
          MaterialPage(
                        // nameというプロパティも存在しますが、こちらはルートのnameなのでどの画面かという情報を渡すには適していないと思われます。
            arguments: PageName.fugaPage,
            child: FugaPage(),
          ),
        if (fooPageTitle.isNotEmpty)
          MaterialPage(
            arguments: PageName.fooPage,
            child: FooPage(title: fooPageTitle),
          )
      ],
      onPopPage: (route, result) {
        // 戻る先の画面がない場合にはfalse返す
        if (!route.didPop(result)) {
          return false;
        }
                 // 戻る挙動の元の画面をpagesから除く為に値を戻したりする
        final pageName = route.settings.arguments as PageName;
        switch (pageName) {
          case PageName.fugaPage:
            ref.read(showFugaPageProvider.notifier).state = false;
            break;
          case PageName.fooPage:
            ref.read(fooPageTitleProvider.notifier).state = "";
            break;
          default:
            break;
        }
        return true;
      },
    );
  }

  @override
  Future<void> setNewRoutePath(void configuration) async {}
}


final showFugaPageProvider =
    StateProvider.autoDispose<bool>((ref) => false);

final fooPageTitleProvider = StateProvider<String>((ref) => "");

でこれを使いたいWidgetのところに置いてあげる

使いたいwidget.dart
Container(
  child: Router(routerDelegate: CustomRouterDelegate(ref));
)

ざっくり実装を載せましたがこんな感じでいけます。

私がこれを実装するまでに起こった事象

・どこかのサイトを見てnavigatorKeyをCustomRouterDelegateのコンストラクタのところでインスタンス生成してしまっていたため、画面遷移animationが消える
・onPopPageのところでproviderに値を戻す操作をしていなかったため、戻るボタンで戻ってきた後に再度画面遷移しようとしたら反応しなくなってしまう

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?