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

修改Flutter.java

原本的依赖如下

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

将报错部分替换为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 = 0
layout.bottomMargin = 26
addContentView(flutterView, layout)
}

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

在Android项目中接入Flutter,在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项目中接入Flutter,在Flutter使用安卓布局---草稿

获取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_ KaTeX parse error: Expected '}', got 'EOF' at end of input: …ndroid的Text数值是:{counterData.counterData}”
result.success(counterData.counterData)
}
“decreaseNumber” -> {
counterData.counterData–
myText.text = “当前Android的Text数值是:${c 在Android项目中接入Flutter,在Flutter使用安卓布局---草稿
ounterData.counterData}”
result.success(counterData.counterData)
}
“decreaseSize” -> {
if(myText.textSize > 0){
val size = myText.textSize
myText.setTextSize(TypedValue.COMPLEX_UNIT_PX,size-1)
result.success(myText.textSize)
} else{
result.error(“出错”, “size无法再小了!”, null)
}
}
“increaseSize” -> {
if(myText.textSize < 100){
val size = myText.textSize
myText.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) {
return;
}
widget.counterController.setId(id);
}

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

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

上一篇:Flutter性能总结


下一篇:android图片处理,flutter跳转动画