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