flutter中嵌入原生Android View

一、创建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() {
    }
}

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Flutter是一种跨平台的移动应用开发框架,可以同时在iOS和Android上运行。Flutter使用Dart语言编写,具有热重载功能,可以快速开发高性能、美观的应用程序。Flutter的UI是自己绘制的,不依赖于操作系统的原生控件,因此可以实现高度自定义的UI效果。 Android原生开发是指使用Java或Kotlin编写Android应用程序,使用Android SDK提供的原生控件和API。原生应用程序可以充分利用Android操作系统的功能和性能,但需要针对不同的设备和版本进行适配。 总的来说,FlutterAndroid原生开发的区别在于开发语言、UI实现方式和跨平台能力。Flutter使用Dart语言,UI自绘,可以跨平台运行;而Android原生开发使用Java或Kotlin语言,依赖于操作系统的原生控件和API,只能在Android上运行。 ### 回答2: Flutter是一个开源的移动应用开发框架,而Android原生是指使用Java或Kotlin等本地语言编写的应用程序。下面是FlutterAndroid原生之间的主要区别: 1. 学习曲线:Flutter使用Dart语言开发,如果你已经熟悉了JavaScript或Java等其他语言,学习Flutter也许会花费你一些时间。但是Flutter的开发文档与工具是易于理解和使用的,所以Flutter的学习曲线相对于Android原生会更加平缓。 2. 性能:Flutter使用自己的渲染引擎来绘制用户界面,其称为“Skia”。与Android原生相比,Flutter在UI性能上可能会有一些优势。Flutter采用了一些复杂的技术来在运行时优化代码,并且可以使用Google的Dart编译器来生成高效的原生代码。 3. 开发效率:Flutter的开发速度相对于Android原生也许更快。由于Flutter的热重载功能,您可以更快地查看您所做的更改,并在不刷新应用程序的情况下保存这些更改。此外,Flutter具有很好的跨平台开发支持,您可以在同一代码库以相同的方式开发iOS和Android应用。 4. 生态系统:Flutter生态系统的插件和库数量与Android原生相比仍然不足。但是,越来越多的开发人员和组织机构开发了各种各样的插件和库来帮助Flutter开发人员快速开发应用。 5. 设计自由度:Flutter相对于Android原生提供了更多灵活的设计自由度。Flutter应用程序可以组合使用各种小部件和布局,以创建非常独特的用户界面和动画效果。 综上所述,FlutterAndroid原生的区别在于性能、学习曲线、开发效率、生态系统和设计自由度等方面。选择一种适合自己的框架取决于您的具体需求和项目要求,需要根据实际情况进行权衡。 ### 回答3: Flutter(也称为Flutter UI框架)是一个跨平台的移动应用程序开发框架,由谷歌(Google)开发。 它允许开发人员以一种统一的语言(Dart)构建高性能,高保真度的移动应用程序,可在Android和iOS等平台上运行。Flutter基于自己的渲染引擎和框架建立,其包括许多构建UI的内置组件。Flutter具有以下区别和优势: 1.基于Dart语言:与Java和Kotlin不同,Dart是一种强类型静态语言,也支持动态语言特性。Flutter的完整生态系统都是Dart编写,因此开发人员可以在编写Flutter代码时使用所有Dart的语言特性。 2.完全自定义UI:Flutter的Widget框架提供了大量的预置组件,可以自定义和扩展,使得开发人员可以自由地构建独特的,自定义的UI。 3.高性能:Flutter 框架可以通过达到每秒60帧(FPS)的性能来实现对动画和过渡的支持,这是传统的基于WebView的Hybrid移动应用程序难以匹敌的。 4.快速迭代和快速开发:由于Flutter使用Hot reloading可以快速加载并重新加载UI,因此可以大大减少调试时间和部署时间。 5.跨平台开发:Flutter 允许开发人员在所有平台上构建相同的应用程序,包括Android和iOS,从而实现在延长开发周期的同时实现保证强一致性的开发。 与Flutter相比,Android原生的开发主要集在Java和Kotlin之上,以使用Android SDK为框架,以构建在Android原生应用程序。而Android原生的应用程序开发具有以下优势和限制: 1.更快的性能:Android原生应用程序始终是高性能的,因为它们直接在设备上运行而不需要间层。 2.外观和风格与设备一致:为了确保Android应用程序看起来和操作体验与设备相同,Android原生开发支持通过设置特定的样式,颜色和控件来实现此目的。 3.专业开发支持:Android原生应用程序开发具有良好的集成开发环境,具有权限系统,可提供良好的面向开发人员的支持。 4.固定生态系统:Android原生应用程序必须在特定版本的Android API上运行,这意味着必须使用不同的软件包,类和框架,这可能会引起问题。 总之,FlutterAndroid原生应用程序开发是为相同平台开发应用程序的两种不同方法。Flutter提供了快速迭代和跨平台开发的优势,而Android原生应用程序则提供了更快的性能可靠性和与设备外观和风格的一致性优势。根据不同的需求,开发人员可以选择使用适合他们需求的一种或同时使用这两种方式来开发移动应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值