flutter 可实现将原生页面托管到 Flutter UI 中,并支持混合和虚拟显示模式。
混合模式,将原生 android.view.View 直接添加到 flutter 的视图中。能保持View 大部分功能。
虚拟模式,是将原生 android.view.View 作为实例渲染成纹理,个别功能无法正常。
实现方法
混合和虚拟模式,使用区别只在 dart 代码中
混合模式
Widget build(BuildContext context) {
const String viewType = '<platform-view-type>'; //托管页面标识
final Map<String, dynamic> creationParams = <String, dynamic>{}; //传入原生页面的参数
return Scaffold(
body: PlatformViewLink(
surfaceFactory: (context, controller) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{});
},
onCreatePlatformView: (params) {
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
viewType: viewType),
);
}
虚拟模式
Widget build(BuildContext context) {
const String viewType = '<platform-view-type>'; //托管页面标识
final Map<String, dynamic> creationParams = <String, dynamic>{}; //传入原生页面的参数
return Scaffold(
body: return AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);,
);
}
安卓原生代码
使用同一份安卓原生代码
package com.example.test
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.webkit.WebView
import android.webkit.WebViewClient
import io.flutter.plugin.platform.PlatformView
@SuppressLint("SetTextI18n")
internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?): PlatformView {
private val webView: WebView
override fun getView(): View? {
return webView
}
override fun dispose() {
TODO("Not yet implemented")
}
init {
webView = WebView(context)
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
}
}
webView.settings.apply {
useWideViewPort = true
loadWithOverviewMode = true
javaScriptEnabled = true
domStorageEnabled = true
allowContentAccess = true
allowFileAccess = true
setSupportZoom(true)
}
webView.loadUrl("https://m.zebanapp.com")
}
}
总结
将 安卓原生 View 托管给 Flutter UI,能更好地使用实现原生功能。但另外一方面,将安卓原生 View 托管Flutter UI 必然会造成一些性能上的损失。更多缓解方法可以参考