美文网首页
flutter学习之嵌入原生View - android

flutter学习之嵌入原生View - android

作者: BlueSocks | 来源:发表于2023-01-12 15:10 被阅读0次
    • 本文主要介绍如何在 flutter中加载原生android的view,之前我们介绍了flutter加载iOS view。原理也是类似。

    1. 创建android中view

    我们是iOS开发,这里简单介绍下如何加载原生android的view,其流程和我们iOS view类似。

    我们在android项目的创建一个测试view

    package com.example.flutter_android_view
    import android.content.Context
    import android.view.View
    import android.widget.TextView
    import io.flutter.plugin.common.BinaryMessenger
    import io.flutter.plugin.platform.PlatformView
    
    class TestView(context: Context, messenger: BinaryMessenger, viewId: Int, args: Map<String, Any>?) :
        PlatformView {
    
        private val textView: TextView = TextView(context)
    
        init {
            textView.text = "这是一个Android View"
        }
    
        override fun getView(): View {
    
            return textView
        }
    
        override fun dispose() {
            TODO("Not yet implemented")
        }
    }
    
    

    我们继续创建TestViewFactory

    import android.content.Context
    import io.flutter.plugin.common.BinaryMessenger
    import io.flutter.plugin.common.StandardMessageCodec
    import io.flutter.plugin.platform.PlatformView
    import io.flutter.plugin.platform.PlatformViewFactory
    
    class TestViewFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    
        override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
            return TestView(context, messenger, viewId, args as Map<String, Any>?)
        }
    
    }
    
    

    创建TestPlugin

    import io.flutter.embedding.engine.plugins.FlutterPlugin
    import io.flutter.plugin.common.BinaryMessenger
    import io.flutter.plugin.common.PluginRegistry
    
    class TestViewPlugin : FlutterPlugin {
    
        override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
            val messenger: BinaryMessenger = binding.binaryMessenger
            binding
                .platformViewRegistry
                .registerViewFactory(
                    "plugins.flutter.io/custom_platform_view", TestViewFactory(messenger))
        }
    
        companion object {
            @JvmStatic
            fun registerWith(registrar: PluginRegistry.Registrar) {
                registrar
                    .platformViewRegistry()
                    .registerViewFactory(
                        "plugins.flutter.io/custom_platform_view",
                        TestViewFactory(registrar.messenger()))
            }
        }
    
        override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
    
        }
    }
    
    

    App 中 MainActivity 中注册:

    package com.example.flutter_android_view
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    
    class MainActivity: FlutterActivity() {
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            flutterEngine.plugins.add(TestViewPlugin())
        }
    }
    
    

    最后的目录结构

    image.png

    嵌入flutter

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class AndroidViewPage extends StatelessWidget {
      const AndroidViewPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        String? title = "androidView";
    
        return Scaffold(
    
          appBar: AppBar(title: Text(title ?? ''),),
          body: Center(
            child:iosView(),
          ),
        );
      }
      Widget iosView() {
        if(defaultTargetPlatform == TargetPlatform.android){
          return  const AndroidView(
            viewType: 'plugins.flutter.io/custom_platform_view',
          );
        }else {
          return Container();
        }
      }
    }
    
    

    使用android模拟器运行结果

    image.png

    2. Flutter向android传值

    AndroidView(
      viewType: 'plugins.flutter.io/custom_platform_view',
       creationParams: {'text': 'Flutter传给Android中TextView的参数'},
       creationParamsCodec: StandardMessageCodec(),
    );
    
    

    这里viewType就是我们注册的时候使用的标识符creationParams为创建AndroidView时带的参数creationParamsCodec:将 creationParams 编码后再发送给平台侧,它应该与传递给构造函数的编解码器匹配

    我们在Android项目中TestView判断是否传递了参数

    init {
        args?.also {
            textView.text = it["text"] as String
        }
    }
    
    
    image.png

    我们在运行中通过按钮点击改变AndroidView的内容

    static const platform = MethodChannel('com.flutter.test.TestView');
    
    

    我们在flutter页面定义一个方法通道

    RaisedButton( child: const Text('传递参数给原生View'), onPressed: () { platform.invokeMethod('userInfo', {'name': 'Jack', 'city': "New York"}); },
    
    
    

    点击的时候传参给Android页面,我们在onMethodCall方法中获取我们的参数

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        if (call.method == "userInfo") {
    
            val name = call.argument("name") as String?
            val city = call.argument("city") as String?
    
            textView.text = "my Name is:,$name,from:$city"
        } else {
            result.notImplemented()
        }
    }
    
    

    3. 小结

    关于 android中view的传值逻辑基本和之前的iOS页面差不多,逻辑上都是通过viewID来标记唯一性来确定,根据一些key, method方法等进行交互回调函数的相互回调实现通信

    本文转自 https://juejin.cn/post/7113187699028131877,如有侵权,请联系删除。

    相关文章

      网友评论

          本文标题:flutter学习之嵌入原生View - android

          本文链接:https://www.haomeiwen.com/subject/gmkwcdtx.html