likes
comments
collection
share

Flutter 多引擎渲染,混合嵌套滚动探索

作者站长头像
站长
· 阅读数 2

背景

前一段时间有个需求是在一个滚动复杂的 Native 页面(多级滚动嵌套)中,嵌入一个 Flutter 列表组件。

先说结论

Flutter + Native 混合嵌套体验并不好,且需要花费更多的维护成本。既然做不到降本增效,那也没必要做这种 KPI 式的事情。所以最后还是用 Native 的 scrollView 来落地。

但整个探索过程还是值得分享给各位同学了解一下。

过程

整体验证过程是在 iOS 上进行的(毕竟笔者是个 iOSer [手动狗头])。

还有一点要说一下测试工程找不到了 ... 只有当时文档上留的一些截图,所以没办法直接代码上加注释。

提前做

在 iOS 上,FlutterView 响应优先级很低,Flutter 响应的是 touch 相关事件,会被上层的手势拦截,如果上层有滑动或者点击事件就会产生 Flutter 操作上无响应的问题。

(关于 Flutter 响应原理这里不过多阐述,有兴趣的同学可以找一下相关的文章)

解决方式上,在 FlutterViewController 上增加常用的点击、滑动等手势,来保证 FlutterView 作为子视图能优先响应而不被父视图上的手势事件拦截。

- (void)setupGestureRecognizer {
    // 增加滑动手势
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
    panGestureRecognizer.cancelsTouchesInView = NO;
    [self.flutterViewController.view addGestureRecognizer:panGestureRecognizer];
    
    // 增加点击手势
    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.flutterViewController.view addGestureRecognizer:tapGestureRecognizer];
}

方案一:各自处理滚动

Native 的 UIScrollViewFlutterView 是相互独立,处理自身滚动。

适用场景:不需要惯性联动的场景(比如上滑后吸顶,再次滑动再进行 flutter 滚动)。

关键测试代码如下:

Flutter 多引擎渲染,混合嵌套滚动探索

测试上,超过一定滚动距离就禁用 Native UIScrollView 滚动,再次滚动时, FlutterView 就会响应并滚动。

好处是不需要什么冲突处理。当然在需要联动场景,就是完全的撕裂,不符合我们的要求。

方案二:Native 控制,Flutter 跟随

Native UIScrollView 响应手势事件, Flutter 根据 messageChannel 实时传输的滚动距离跟随滚动。

关键测试代码如下:

Flutter 多引擎渲染,混合嵌套滚动探索

gridViewComponent 是测试用的 Flutter UI 滚动组件,提供了一个封装好的 scrollTo 方法,内部是 messageChannel 进行通信。

Flutter 多引擎渲染,混合嵌套滚动探索

原理简单的说,就是 FlutterView 不响应手势,滚动由外部 UIScrollView 统一控制,FlutterView 反馈给 iOS 当前内部滚动的状态。

优点:

能跟现有 Native 代码较好的融合,也不需要更多的改造现有代码逻辑。

缺点:

  • 割裂了 Flutter 的完整性,Flutter 需要增加更多的逻辑判断(比如滚动是否到底,加载更多可能也不能用第三方库)。
  • (需测试)messageChannel 通信上性能不算太好,可能要验证各类机型是否会出现抖动问题。

方案三:Flutter 控制,Native 跟随

FlutterView 响应手势事件,获取到的滚动参数,回传给 Native,来控制 UIView 的布局位置。

关键测试代码如下:

Flutter 多引擎渲染,混合嵌套滚动探索

gridViewComponent 提供了一个封装好的 handleScroll 的回调方法,把滚动 Y 轴信息传回 Native,Native 重新布局 UIView

效果如下:

Flutter 多引擎渲染,混合嵌套滚动探索

可以看到小绿块(UIView)位置确实在跟随 FlutterView 滚动变化。

优点:FlutterView 逻辑上更完整。

缺点:在 Native 上要处理更多的逻辑。

后续

在 Android 上还有另一个问题,Android 设备种类繁多,各种魔改,比如 Flutter 在 Android 华为设备存在滚动惯性跟其他机型不一致的问题,惯性偏短。

所以结论上,Flutter 多引擎渲染来做部分嵌套滚动不大可行。需要踩更多的坑。

如果对你开发学习上有丝丝作用,请点个赞[开心] ~