Flutter导航管理插件riverpod_navigation的使用
Flutter导航管理插件riverpod_navigation的使用
管理Flutter导航可以使用riverpod
插件。本文将详细介绍如何使用riverpod_navigation
插件来管理应用的导航。
使用
引导
替换你的根ProviderScope
为一个带有路由层次结构的RiverpodNavigation
小部件,并给定提供的delegate
和parser
到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( // 替换你的根ProviderScope
routes: routes,
builder: (context, delegate, parser) => MaterialApp.router(
title: 'Flutter Demo',
routerDelegate: delegate,
routeInformationParser: parser,
),
);
导航
从Provider访问
暴露了一个navigationProvider
,可以用来读取当前的导航状态。
要访问允许各种操作的基础通知器,可以使用navigationProvider.notifier
。
final myProvider = Provider<MyState>((ref) {
final navigation = ref.watch(navigationProvider.notifier);
return MyState(
navigateToArticles: () {
navigation.navigate(Uri.parse('/articles'))
},
pop: () {
navigation.pop();
}
);
},
);
从BuildContext访问
可以通过BuildContext
的navigation
扩展方法访问通知器。
[@override](/user/override)
Widget build(BuildContext context) {
return TextButton(
child: Text('Articles'),
onPressed: () {
context.navigation.navigate(Uri.parse('/articles'))
}
);
}
返回行为
为了自定义返回时的弹出行为,可以在RiverpodNavigation
实例中提供一个PopBehavior
回调。结果表示当前弹出动作是否应该更新、取消或采用默认行为(即简单地用父路由替换当前路由)。
RiverpodNavigation(
popBehaviour: (notifier, stack) {
if (stack.lastRoute?.key == Key('share-article')) {
return PopResult.update(Uri.parse('/'));
}
return PopResult.auto();
},
// ...
)
URI重写
可以在URI被路由器处理之前对其进行修改,通过提供uriRewriter
属性。这可以用于重定向或规范化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;
},
// ...
);
完整示例Demo
以下是一个完整的示例Demo,展示了如何使用riverpod_navigation
插件。
import 'package:example/layouts/about.dart';
import 'package:example/layouts/article.dart';
import 'package:example/layouts/home.dart';
import 'package:example/layouts/tabs/all_articles.dart';
import 'package:example/layouts/tabs/shop.dart';
import 'package:example/layouts/tabs/update_profile.dart';
import 'package:example/layouts/tabs/user.dart';
import 'package:flutter/material.dart';
import 'package:riverpod_navigation/riverpod_navigation.dart';
import 'layouts/share.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
final routes = RouteDefinition(
key: Key('Home'),
template: UriTemplate.parse('/'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: HomeLayout(
activeTab: activeTab,
tabs: tabs,
),
),
tabs: [
RouteDefinition(
template: UriTemplate.parse('/all-articles'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: AllArticlesLayout(),
),
),
RouteDefinition(
template: UriTemplate.parse('/shop'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: ShopLayout(),
),
),
RouteDefinition(
template: UriTemplate.parse('/user'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: UserLayout(),
),
next: [
RouteDefinition(
template: UriTemplate.parse('/update-profile'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: UpdateProfileLayout(),
),
),
],
),
],
next: [
RouteDefinition(
template: UriTemplate.parse('/articles/:id'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: ArticleLayout(
id: entry.parameter('id'),
),
),
next: [
RouteDefinition(
template: UriTemplate.parse('/share'),
key: Key('share'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: ShareLayout(
articleId: entry.parameter('id'),
),
),
),
],
),
RouteDefinition(
template: UriTemplate.parse('/about'),
builder: (context, entry, tabs, activeTab) => MaterialPage(
child: AboutLayout(),
),
),
],
);
return RiverpodNavigation(
routes: routes,
uriRewriter: (notifier, uri) {
const publicPrefix = 'https://example.com';
final stringUri = uri.toString();
if (stringUri.startsWith(publicPrefix)) {
return Uri.parse(stringUri.substring(publicPrefix.length));
}
return uri;
},
popBehaviour: (notifier, stack) {
if (stack.lastRoute?.key == Key('share')) {
return PopResult.update(Uri.parse('/'));
}
return PopResult.auto();
},
builder: (context, delegate, parser) => MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate: delegate,
routeInformationParser: parser,
),
);
}
}
更多关于Flutter导航管理插件riverpod_navigation的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter导航管理插件riverpod_navigation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
riverpod_navigation
是一个结合了 Riverpod
状态管理和 Flutter 导航功能的插件,旨在简化应用中的路由管理和状态共享。它提供了一种声明式的方式来处理导航,并且能够与 Riverpod
无缝集成。
以下是使用 riverpod_navigation
的基本步骤和一个简单的示例:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 riverpod_navigation
依赖:
dependencies:
flutter:
sdk: flutter
riverpod: ^2.0.0
riverpod_navigation: ^0.1.0
然后运行 flutter pub get
来安装依赖。
2. 创建路由状态提供者
使用 riverpod_navigation
的 NavigationProvider
来管理路由状态。你可以创建一个全局的 Provider
来管理导航栈。
import 'package:riverpod/riverpod.dart';
import 'package:riverpod_navigation/riverpod_navigation.dart';
final navigationProvider = StateNotifierProvider<NavigationNotifier, NavigationState>((ref) {
return NavigationNotifier();
});
3. 定义路由
在你的应用中定义路由。你可以使用 MaterialPageRoute
或其他类型的路由。
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
context.read(navigationProvider.notifier).push('/details');
},
child: Text('Go to Details'),
),
),
);
}
}
class DetailsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Details'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
context.read(navigationProvider.notifier).pop();
},
child: Text('Go back'),
),
),
);
}
}
4. 配置导航
在 MaterialApp
中使用 riverpod_navigation
的 Navigation
组件来管理导航。
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_navigation/riverpod_navigation.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Navigation(
provider: navigationProvider,
routes: {
'/': (context) => HomePage(),
'/details': (context) => DetailsPage(),
},
),
);
}
}
5. 使用导航
在你的应用中使用 context.read(navigationProvider.notifier)
来执行导航操作,例如 push
和 pop
。
onPressed: () {
context.read(navigationProvider.notifier).push('/details');
},
6. 处理深链接
riverpod_navigation
也支持处理深链接。你可以在 NavigationNotifier
中定义深链接的处理逻辑。
final navigationProvider = StateNotifierProvider<NavigationNotifier, NavigationState>((ref) {
return NavigationNotifier()..handleDeepLink('/initialPath');
});