flutter中嵌入原生Android View

it2024-10-19  37

一、创建Android原生View

1、选中android目录下任意文件,点击右上角出现的“Open for Editing in Android Studio”

2、在新打开的窗口里,app项目下创建继承PlatformView 的AndroidView

/** * messenger flutter与原生通讯需要该参数 * viewId 控件唯一标识 * args 初始化参数 */ class AndroidView(context: Context?, messenger: BinaryMessenger, viewId: Int, args: Any?) : PlatformView { private val textView = TextView(context) init { textView.text = "这是AndroidView" } override fun getView(): View { return textView } override fun dispose() { } }

二、注册AndroidView

1、创建继承PlatformViewFactory的AndroidFactory

/** * messenger flutter与原生通讯需要该参数 */ class AndroidFactory(val messenger: BinaryMessenger): PlatformViewFactory(StandardMessageCodec.INSTANCE) { override fun create(context: Context?, viewId: Int, args: Any?): PlatformView { return AndroidView(context, messenger, viewId, args) } }

2、创建继承FlutterPlugin的AndroidPlugin

class AndroidPlugin : FlutterPlugin{ override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { //这里“AndroidView”要和flutter中创建的AndroidView的viewType属性值一致 binding.platformViewRegistry .registerViewFactory("AndroidView", AndroidFactory(binding.binaryMessenger)) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { } }

3、在MainActivity中添加AndroidPlugin

class MainActivity: FlutterActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) flutterEngine.plugins.add(AndroidPlugin()) } }

三、Flutter中嵌入AndroidView

class AndroidViewDemo extends StatelessWidget{ @override Widget build(BuildCotext context) { return Scaffold( appBar: Appbar(), body: Center( child: AndroidView( viewType: 'AndroidView', ), ) ); } }

------------------------------------------------------------------------进阶----------------------------------------------------------------------------------

四、创建AndroidView时传参

1、flutter端修改

class AndroidViewDemo extends StatelessWidget{ @override Widget build(BuildCotext context) { return Scaffold( appBar: Appbar(), body: Center( child: AndroidView( viewType: 'AndroidView', creationParams: {'initText': '这是flutter初始化传参'}, creationParamsCode: StandardMessageCode(),//这里编码器要和PlatformViewFactory构造方法定义的解码器匹配 ), ) ); } }

2、Android端修改

/** * messenger flutter与原生通讯需要该参数 * viewId 控件唯一标识 * args 初始化参数 */ class AndroidView(context: Context?, messenger: BinaryMessenger, viewId: Int, args: Any?) : PlatformView { private val textView = TextView(context) init { textView.text = "这是AndroidView" if (args is Map<*, *>){ textView.text = args["initText"] as String } } override fun getView(): View { return textView } override fun dispose() { } }

五、flutter向AndroidView发送数据

1、flutter端修改

class AndroidViewDemo extends StatefulWidget { @override State<StatefulWidget> createState() { return AndroidViewDemoState(); } } class AndroidViewDemoState extends State<AndroidViewDemo>{ MethodChannel methodChannel = MethodChannel("AndroidView"); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( width: double.infinity, height: 60, child: AndroidView( viewType: 'AndroidView', creationParams: {'initText': '这是flutter初始化传参'}, creationParamsCodec: StandardMessageCodec(), ), ), RaisedButton( child: Text("向AndroidView传递参数"), onPressed: () { methodChannel .invokeMethod('setText', {'text': '这是flutter给AndroidView传参'}); }, ), ], ); } }

2、Android端修改

/** * messenger flutter与原生通讯需要该参数 * viewId 控件唯一标识 * args 初始化参数 */ class AndroidView(context: Context?, messenger: BinaryMessenger, viewId: Int, args: Any?) : PlatformView, MethodChannel.MethodCallHandler { private val textView = TextView(context) private val methodChannel = MethodChannel(messenger, "AndroidView") init { textView.text = "这是AndroidView" if (args is Map<*, *>){ textView.text = args["initText"] as String } methodChannel.setMethodCallHandler(this) } override fun getView(): View { return textView } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when { call.method == "setText" -> { //flutter向AndroidView发送数据 val text = call.argument<String>("text") textView.text = text } else -> result.notImplemented() } } override fun dispose() { } }

六、flutter从AndroidView获取数据

1、flutter端修改

class AndroidViewDemo extends StatefulWidget { @override State<StatefulWidget> createState() { return AndroidViewDemoState(); } } class AndroidViewDemoState extends State<AndroidViewDemo>{ MethodChannel methodChannel = MethodChannel("AndroidView"); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( width: double.infinity, height: 60, child: AndroidView( viewType: 'AndroidView', creationParams: {'initText': '这是flutter初始化传参'}, creationParamsCodec: StandardMessageCodec(), ), ), RaisedButton( child: Text("向AndroidView传递参数"), onPressed: () { methodChannel .invokeMethod('setText', {'text': '这是flutter给AndroidView传参'}); }, ), RaisedButton( child: Text("从AndroidView获取参数"), onPressed: () async { var result = await methodChannel.invokeMethod('getText'); setState(() { text = result['text']; }); }, ), Text("$text") ], ); } }

2、Android端修改

/** * messenger flutter与原生通讯需要该参数 * viewId 控件唯一标识 * args 初始化参数 */ class AndroidView(context: Context?, messenger: BinaryMessenger, viewId: Int, args: Any?) : PlatformView, MethodChannel.MethodCallHandler { private val textView = TextView(context) private val methodChannel = MethodChannel(messenger, "AndroidView") init { textView.text = "这是AndroidView" if (args is Map<*, *>){ textView.text = args["initText"] as String } methodChannel.setMethodCallHandler(this) } override fun getView(): View { return textView } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when { call.method == "setText" -> { //flutter向AndroidView发送数据 val text = call.argument<String>("text") textView.text = text } call.method == "getText" -> { //flutter从AndroidView获取数据 result.success(mapOf("text" to "这是从AndroidView获取参数")) } else -> result.notImplemented() } } override fun dispose() { } }

七、页面多个相同的原生View通讯问题(多个AndroidView时发送数据只有最后一个收到)

方案:构建不同名称的name的MethodChannel

1、flutter端修改

class AndroidViewDemo extends StatefulWidget { @override State<StatefulWidget> createState() { return AndroidViewDemoState(); } } class AndroidViewDemoState extends State<AndroidViewDemo>{ var methodChannels = []; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( width: double.infinity, height: 60, child: AndroidView( viewType: 'AndroidView', creationParams: {'initText': '这是flutter初始化传参'}, onPlatformViewCreated: (viewId){ methodChannels.add(MethodChannel("AndroidView_$viewId")); }, creationParamsCodec: StandardMessageCodec(), ), ), Container( width: double.infinity, height: 60, child: AndroidView( viewType: 'AndroidView', creationParams: {'initText': '这是flutter初始化传参'}, onPlatformViewCreated: (viewId){ methodChannels.add(MethodChannel("AndroidView_$viewId")); }, creationParamsCodec: StandardMessageCodec(), ), ), RaisedButton( child: Text("向第一个AndroidView传递参数"), onPressed: () { methodChannels[0] .invokeMethod('setText', {'text': '这是flutter给AndroidView传参'}); }, ), RaisedButton( child: Text("向第二个AndroidView传递参数"), onPressed: () { methodChannels[1] .invokeMethod('setText', {'text': '这是flutter给AndroidView传参'}); }, ), RaisedButton( child: Text("从AndroidView获取参数"), onPressed: () async { var result = await methodChannel.invokeMethod('getText'); setState(() { text = result['text']; }); }, ), Text("$text"), ], ); } }

2、Android端修改

/** * messenger flutter与原生通讯需要该参数 * viewId 控件唯一标识 * args 初始化参数 */ class AndroidView(context: Context?, messenger: BinaryMessenger, viewId: Int, args: Any?) : PlatformView, MethodChannel.MethodCallHandler { private val textView = TextView(context) private val methodChannel = MethodChannel(messenger, "AndroidView_$viewId") init { textView.text = "这是AndroidView" if (args is Map<*, *>){ textView.text = args["initText"] as String } methodChannel.setMethodCallHandler(this) } override fun getView(): View { return textView } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when { call.method == "setText" -> { //flutter向AndroidView发送数据 val text = call.argument<String>("text") textView.text = text } call.method == "getText" -> { //flutter从AndroidView获取数据 result.success(mapOf("text" to "这是从AndroidView获取参数")) } else -> result.notImplemented() } } override fun dispose() { } }

 

最新回复(0)