写点什么

在 Android 项目中接入 Flutter,在 Flutter 使用安卓布局 --- 草稿

用户头像
Android架构
关注
发布于: 刚刚

import androidx.annotation.NonNull;import androidx.fragment.app.Fragment;

修改 Flutter.java

原本的依赖如下



将报错部分替换为 androidx 的版本


import androidx.annotation.NonNull;import androidx.lifecycle.Lifecycle;import androidx.lifecycle.LifecycleObserver;import androidx.lifecycle.OnLifecycleEvent;


那么现在,androidx 带来的问题就解决了,下面就开始准备正式接入 Flutter

在 flutter 中编辑入口

进入 my_flutter 目录中的 lib 目录,可以看到会有系统自带的 main.dart 文件,这是一个默认的计数器页面,我们修改一部分:


void main() => runApp(getRouter(window.defaultRouteName));Widget getRouter(String name) {switch (name) {case 'route1':return MyApp();default:return Center(child: Text('Unknown route: $name', textDirection: TextDirection.ltr),);}}


将入口更换为通过“route1" 命名进入进入


接下来就是在 android 中进行操作了

在 android 中接入 flutter

进入到 android 项目,在 MainActivity 中,我们做如下操作:


bt_flutter.setOnClickListener {val flutterView = Flutter.createView(this@MainActivity,lifecycle,"route1")val layout = ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)layout.leftMargin = 0layout.bottomMargin = 26addContentView(flutterView, layout)}


从上面的代码可以看到,我们通过一个按钮的点击事件去展示了 flutter 的计数器页面。实际效果如下:



那么 android 接入 flutter 就结束了,下面是在 flutter 中接入 android

在 Flutter 中接入 android 界面

我们可以新建一个 flutter 项目,用于测试这个例子


因为用到了 kotin,所以使用以下命令


flutter create -a kotlin counter_native


flutter create -a kotlin counter_native

获取 android 数据

关于如何去获取数据,主要还是使用 MethodChannel


看一下 android 中 MainActivity 的代码


class MainActivity: FlutterActivity() {private val channelName = "samples.flutter.io/counter_native";override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)GeneratedPluginRegistrant.registerWith(this)MethodChannel(flutterView, channelNameTwo).setMethodCallHandler { methodCall, result ->when(methodCall.method){"getCounterData" -> {result.success(getCounterData())}else -> {result.notImplemented();}}}}private fun getCounterData():Int{return 100;}}


在 MethodChannel 的结果回调中,我们进行了筛选,如果方法名是 getCounterData 就直接返回 100


接下来在 flutter 中编写下面的代码:


static const platform =const MethodChannel('samples.flutter.io/counter_native');void getCounterData() async {int data;try {final int result = await platform.invokeMethod('getCounterData');data = result;} on PlatformException catch (e) {data = -999;}setState(() {counterData = data;});}


效果如下:



获取 android 的数据就说到这里,下面就是去获取 android 的页面了

获取 android 的布局

相较于数据而言,拿到 android 的布局就要复杂的多

创建 android 视图

在 android 项目里面,创建一个想要展示在 flutter 中的布局,这里,我们结合 xml 文件来创建布局,不过使用 xml 的方式,会出现 R 文件找不到的情况,这时候编译器会报错,暂时不用去管:


class CounterView(context: Context, messenger: BinaryMessenger, id: Int): PlatformView, MethodChannel.MethodCallHandler {private var methodChannel: MethodChannel =MethodChannel(messenger, "samples.flutter.io/counter_view_$id")private var counterData: CounterData = CounterData()private var view: View = LayoutInflater.from(context).inflate(R.layout.test_layout, null);private var myText: TextViewinit {methodChannel.setMet


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


hodCallHandler(this)myText = view.findViewById(R.id.tv_counter)}override fun getView(): View {return view}override fun dispose() {}override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {when (methodCall.method) {"increaseNumber" -> {counterData.counterData++myText.text = "当前 Android 的 Text 数值是:{counterData.counterData}"result.success(counterData.counterData)}"decreaseNumber" -> {counterData.counterData--myText.text = "当前Android的Text数值是:{counterData.counterData}"result.success(counterData.counterData)}"decreaseSize" -> {if(myText.textSize > 0){val size = myText.textSizemyText.setTextSize(TypedValue.COMPLEX_UNIT_PX,size-1)result.success(myText.textSize)} else{result.error("出错", "size 无法再小了!", null)}}"increaseSize" -> {if(myText.textSize < 100){val size = myText.textSizemyText.setTextSize(TypedValue.COMPLEX_UNIT_PX,size+1)result.success(myText.textSize)} else{result.error("出错", "size 无法再大了!", null)}}"setText" -> {myText.text = (methodCall.arguments as String)result.success(myText.text)}else -> {result.notImplemented();}}}}


上面的 CounterData 类是用于存储数据创建的一个类:


class CounterData(var counterData: Int = 0) {}


接下来,我们创建一个 CounterViewFactory 类用于获取到布局:


class CounterViewFactory(private val messenger: BinaryMessenger): PlatformViewFactory(StandardMessageCodec.INSTANCE) {override fun create(context: Context, id: Int, o: Any?): PlatformView {return CounterView(context, messenger, id)}}


最后创建一个 CounterViewPlugin.kt 文件,它用于注册视图,相当于初始化入口


class CounterViewPlugin{fun registerWith(registrar: Registrar) {registrar.platformViewRegistry().registerViewFactory("samples.flutter.io/counter_view", CounterViewFactory(registrar.messenger()))}}


创建完成后,在 MainActivity 中进行视图注册:


override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)CounterViewPlugin().registerWith(flutterView.pluginRegistry.registrarFor("CounterViewPlugin"))...}


接下来,就是在 flutter 中需要做的一些事情了

在 flutter 中获取 android 视图

在 flutter 里面,想要拿到 android 的视图,需要通过 AndroidView 去获取


Widget build(BuildContext context) {if (Platform.isAndroid) {return AndroidView(viewType: 'samples.flutter.io/counter_view',onPlatformViewCreated: _onPlatformViewCreated,);}return Text('$defaultTargetPlatform 还不支持这个布局');}


在 onPlatformViewCreated 方法中,我们需要创建 MethodChannel ,用于调用 android 中编写的方法,我们可以封装一个 Controller 去处理这些逻辑:


final CounterController counterController;void _onPlatformViewCreated(int id) {if (widget.counterController == null) {

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
在Android项目中接入Flutter,在Flutter使用安卓布局---草稿