背景
项目是原生+Flutter实现。首页都是使用的原生页面4个页面切换:Tabbar
+ViewPager
+Fragment
。
需求
将其中第三个Fragment通过Flutter实现,使用FlutterFragment
承载渲染功能。
问题
- ViewPager使用
setOffscreenPageLimit(4)
实现全部加载,结果现象是:第三个FlutterFragment
直接显示在第一个页面上,并且Touch
事件是第一个Fragment响应。也就是说,第三个FlutterFragment
直接盖在第一个页面之上,并且无Touch
响应。 - 从Fragment1、2、4各自页面跳转业务页面返回后,直接呈现的是
FlutterFragment
内容盖在其他Tab页之上,并且无Event事件。
乱投医
因为项目紧急,没时间排查问题,且渲染相关的场景接触的不多,以为是ViewPager不兼容导致的,换成ViewPager2还是有这个问题。毛线都没解决。
解决
渲染逻辑不受View层代码控制的是什么原因,突然想到了SurfaceView
这家伙不太受原生控制,然后查FlutterFragment源码
///FlutterFragment
@Override
@NonNull
public RenderMode getRenderMode() {
String renderModeName =
getArguments().getString(ARG_FLUTTERVIEW_RENDER_MODE, RenderMode.surface.name());
return RenderMode.valueOf(renderModeName);
}
/** Render modes for a Flutter UI. */
public enum RenderMode {
///通过SurfaceView实现,性能好,但是不能做各种动画和原生View及配合的Z-index操作
surface,
///通过SurfaceTexture实现,此模式的性能不如surface,但此模式下的Flutter UI可以动画和转换及Z-index操作
texture,
///通过ImageReader绘制在Canvas上,最终是通过FlutterImageView实现,如在Flutter UI中嵌入了原生View,一般情况下不需要我们实现。
image
}
默认是通过SurfaceView
实现,我们重写FlutterFragment.getRenderMode
返回RenderMode.texture
,问题得以解决。