0%

FlutterBoost集成后WillPopScope失效问题

FlutterBoost集成后WillPopScope失效问题

问题出现场景一: 在集成FlutterBoost后,打开flutter页面WillPopScope包裹页面,其对返回手势拦截的功能没有生效,手势被原生容器捕捉,由原生路由处理

问题出现场景二: 在集成FlutterBoost后,打开flutter页面WillPopScope包裹页面,部分页面生效,但onWillPop返回true和flase效果一致。

定位问题

flutter源码flutter_boost/lib/src/boost_lifecycle_binding.dartBoostLifecycleBinding类的containerDidShow方法会根据当前容器flutter页面数量,选择是否禁用原生页面手势:

1
2
3
4
5
6
7
8
9
10
11
12
void containerDidShow(BoostContainer container) {
///When this container show,we check the nums of page in this container,
///And change the pop gesture in this container
if (container.pages.length >= 2) {
BoostChannel.instance
.disablePopGesture(containerId: container.pageInfo.uniqueId!);
} else {
BoostChannel.instance
.enablePopGesture(containerId: container.pageInfo.uniqueId!);
}
...忽略部分
}

上面的代码中enablePopGesture是像原生容器发送消息开启原生容器左滑手势;disablePopGesture 是像原生容器发送消息禁止原生容器左滑手势;

这个event我们在业务代码中也可以调用,会覆盖这部分代码,使用时候需慎重,因为同一个原生容器中,也可能包含多个flutter页面。强制开启手势,左滑返回会将多个flutter页面一同返回。enablePopGesture 事件,也是通过uniqueId作为key,容器和业务代码建成的通讯channel,该channel目前只实现了对enablePopGesture 的处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// enable iOS native pop gesture for container matching [containerId]
void enablePopGesture({required String containerId}) {
assert(containerId.isNotEmpty);
BoostChannel.instance.sendEventToNative(containerId, {
'event': 'enablePopGesture',
"args": {'enable': true}
});
}

/// disable iOS native pop gesture for container matching [containerId]
void disablePopGesture({required String containerId}) {
assert(containerId.isNotEmpty);
BoostChannel.instance.sendEventToNative(containerId, {
'event': 'enablePopGesture',
"args": {'enable': false}
});
}

问题分析

  1. 在容器的原生手势开启的时候,WillPopScope是拿不到手势相应的,侧滑会由原生路由处理,这个时候添不添加WillPopScope都没有效果
  2. 在容器的原生手势禁止的时候,页面根据是否包含WillPopScope来判断是否处理flutter侧滑手势,如果有侧滑手势,侧滑路由修的是flutter路由部分,原生容器不受影响。这里注意了,原生容器侧滑手势被禁止,即当当前容器中flutter为路由栈退出后仅剩一个,侧滑手势无人响应,需要手动将原生侧滑手势打开。

containerDidShow 判断page数量是根据容器计算的,也就是我们在跳转flutter页面的时候,带上withContainer = true后,每个flutter页面均会独享一个原生容器。

BoostNavigator.instance.push

1
2
3
4
5
6
Future<T> push<T extends Object?>(
String name, {
Map<String, dynamic>? arguments,
bool withContainer = false,
bool opaque = true,
})

遗留问题

  1. 在容器的原生手势禁止的时候,页面不会根据WillPopScope的onWillPop返回值来判断是否响应侧滑手势,而是均不可侧滑。