Riverpod 导航

使用 riverpod 管理 Flutter 导航。

用法

Bootstrap

将您的根 ProviderScope 替换为 RiverpodNavigation widget,并提供您的路由层次结构,然后将提供的 delegateparser 提供给您的 MaterialApp.router 工厂。

  final routes = RouteDefinition(
      template: UriTemplate.parse('/'),
      builder: (context, entry) => MaterialPage(
        child: HomeLayout(),
      ),
      next: [
        RouteDefinition(
          template: UriTemplate.parse('/articles/:id'),
          builder: (context, entry) => MaterialPage(
            child: ArticleLayout(
              id: entry.parameters['id']!,
            ),
          ),
        ),
      ],
    );
    return RiverpodNavigation( // Replaces your root ProviderScope
      routes: routes,
      builder: (context, delegate, parser) => MaterialApp.router(
        title: 'Flutter Demo',
        routerDelegate: delegate,
        routeInformationParser: parser,
      ),
    );

从 Provider

提供了一个 navigationProvider,可用于读取当前的导航状态。

要访问允许各种操作的底层 Notifier,请使用 navigationProvider.notifier provider。

final myProvider = Provider<MyState>((ref) {
        final navigation = ref.watch(navigationProvider.notifier);
        return MyState(
            navigateToArticles: () {
                navigation.navigate(Uri.parse('/articles'))
            },
            pop: () {
                navigation.pop();
            }
        );
    },
);

从 BuildContext

可以使用 BuildContextnavigation 扩展方法访问 Notifier。

@override
Widget build(BuildContext context) {
    return TextButton(
        child: Text('Articles'),
        onPressed: () {
            context.navigation.navigate(Uri.parse('/articles'))
        }
    );
}

Pop 行为

要自定义导航返回时的 pop 行为,可以将 PopBehavior 回调提供给 RiverpodNavigation 实例。结果指示当前 pop 操作是应该更新、取消还是自动(默认行为,仅用父级路由替换当前路由)。

 RiverpodNavigation(
    popBehaviour: (notifier, stack) {
        if (stack.lastRoute?.key == Key('share-article')) {
          return PopResult.update(Uri.parse('/'));
        }
        return PopResult.auto();
      },
    // ...
 )

URI 重写

在 URI 被路由处理之前,可以使用 uriRewriter 属性修改 URI。这对于重定向或规范化 URI 非常有用。

 RiverpodNavigation(
    uriRewriter: (notifier, uri) {
        if (uri == Uri.parse('/home')) {
            return Uri.parse('/');
        }
        const publicPrefix = 'https://example.com';
        final stringUri = uri.toString();
        if (stringUri.startsWith(publicPrefix)) {
            return Uri.parse(stringUri.substring(publicPrefix.length);
        }
        return uri;
    },
    // ...
);

GitHub

https://github.com/aloisdeniel/riverpod_navigation