我正在用go_router和riverpod开发一个Flutter应用程序,分别用于导航和状态管理,这个应用程序有一个小部件,可以显示实时的摄像头信息,我想“关掉它”,当其他页面堆叠在它上面时释放摄像头。
下面是GoRouter代码的一个示例,没有这样的逻辑。
GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => CameraWidget(),
routes: [
GoRoute(
path: 'page1',
builder: (context, state) => Page1Screen(),
),
],
),
],
)
我的第一个尝试是在GoRoute构建器中加入一些逻辑:
GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
if (state.location == "/") {
return CameraWidget();
}
return Center(child: Text("Camera not visible");
},
routes: [
GoRoute(
path: 'page1',
builder: (context, state) => Page1Screen(),
),
],
),
],
)
但这显然不起作用,因为从“/”转到“/page 1”时,构建器不会再次调用。
然后我想到了使用一个riverpod StateProvider来保持摄像头的“开/关”状态,由GoRouter来操作。
GoRouter(
routes: [
GoRoute(
path: '/',
redirect: (context, state) {
final cameraStateNotifier = ref.read(cameraStateNotifierProvider.notifier);
if (state.location == "/") {
cameraStateNotifier.state = true;
} else {
cameraStateNotifier.state = false;
}
return null;
},
builder: (context, state) => CameraWidget(),
routes: [
GoRoute(
path: 'page1',
builder: (context, state) => Page1Screen(),
),
],
),
],
)
但是这也不起作用,因为很明显redirect
在重建小部件树时被调用,并且在这种情况下禁止更改提供者状态。
以前有人遇到过同样的问题吗?我如何让提供商监听GoRouter的位置更改?
3条答案
按热度按时间owfi6suc1#
**编辑:**此方法似乎不适用于
Navigator.pop()
调用和后退按钮按下。请查看当前接受的答案以获得更好的解决方案。我相信我找到了一个很好的方法。我首先为GoRouter定义了一个提供者,然后定义了第二个提供者来监听
router.routeInformationProvider
。这是一个ChangeNotifier,它在每次路由信息发生变化时都会发出通知。最后,我们可以通过第三个提供者来监听特定位置。我认为这是一个很好的变通办法,即使需要从GoRouter包中导入
src/information_provider.dart
,这并不是故意的。kxxlusnw2#
在对我的previous answer进行进一步测试后,我发现我的go_router方法在
Navigator.pop()
调用或按下后退按钮时不起作用。在深入研究go_router的代码后,我认为切换到Routemaster包会更容易,它似乎与Riverpod集成得更好。到目前为止,我对这一变化非常满意。**编辑:**改进的方法现在使用Routemaster的可观察API。
下面是代码:
fae0ux8s3#
您可以使用GoRouter处理路由更改的一个方法是使用
RouteObserver
:如您所见,现在可以访问小部件上的
didPush()
、didPushNext()
、didPop()
和didPopNext()
方法。