目录
一、flutter调用原生并获取返回
主要通过MethodChannel建立连接。
1.1 flutter部分
初始化
//调用原生的通道,"flutterplugindemo"要和原生部分一致
_channel = MethodChannel('flutterplugindemo');
带参调用
//入参
Map<dynamic, dynamic> map = Map();
map["param"] = "222";
await _channel.invokeMethod("sayHello", map);
回参
//等待回参
Map<dynamic, dynamic> response =
await _channel.invokeMethod("sayHello", map);
print("返回" + response.toString());
示例
import 'dart:async';
import 'package:flutter/services.dart';
class Flutterplugindemo {
MethodChannel _channel;
Flutterplugindemo() {
init();
}
init() {
//调用原生的通道,"flutterplugindemo"要和原生部分一致
_channel = MethodChannel('flutterplugindemo');
}
Future<Map<dynamic, dynamic>> sayHello() async {
//入参
Map<dynamic, dynamic> map = Map();
map["param"] = "222";
//等待回参
Map<dynamic, dynamic> response =
await _channel.invokeMethod("sayHello", map);
print("返回" + response.toString());
return response;
}
}
1.2 原生部分
初始化
MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
"flutterplugindemo");
channel.setMethodCallHandler(this);
会产生onMethodCall回调用来接收flutter调用
获取参数
Map<String, Object> map = (Map<String, Object>) call.arguments;
Log.i("FlutterplugindemoPlugin", "入参:map=" + map.toString());
返回参数
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("1111", "33333");
result.success(resultMap);
示例
package com.example.flutterplugindemo.demo;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class DemoPlugin implements MethodChannel.MethodCallHandler {
public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
"flutterplugindemo");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (call.method.equals("sayHello")) {
Map<String, Object> map = (Map<String, Object>) call.arguments;
Log.i("FlutterplugindemoPlugin", "入参:map=" + map.toString());
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("1111", "33333");
result.success(resultMap);
} else {
result.notImplemented();
}
}
public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
}
}
1.3 使用
直接引入调用即可
flutterplugindemo.sayHello();
示例
import 'package:flutter/material.dart';
import 'package:flutterplugindemo/flutter_plugin_webview.dart';
import 'package:flutterplugindemo/flutterplugindemo.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Flutterplugindemo flutterplugindemo;
@override
void initState() {
super.initState();
flutterplugindemo = Flutterplugindemo();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
flutterplugindemo.sayHello();
},
child: Text("点我"),
),
],
),
),
);
}
}
二、原生调用flutter并返回
2.1 原生部分
初始化
channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
"flutterplugindemo");
带参调动flutter并获取回参
Map<String, Object> map = new HashMap<>();
map.put("5555", "6666");
channel.invokeMethod("sayhello2", map, new MethodChannel.Result() {
@Override
public void success(Object result) {
Map<String, Object> resultMap = (Map<String, Object>) result;
Log.i("FlutterplugindemoPlugin", "回参:map=" + resultMap.toString());
}
@Override
public void error(String errorCode, String errorMessage, Object errorDetails) {
}
@Override
public void notImplemented() {
}
});
示例
package com.example.flutterplugindemo.demo;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class DemoPlugin implements MethodChannel.MethodCallHandler {
private EventChannel.EventSink eventSink;
private MethodChannel channel;
public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),
"flutterplugindemo");
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (call.method.equals("sendEvent2")) {
Map<String, Object> map = new HashMap<>();
map.put("5555", "6666");
channel.invokeMethod("sayhello2", map, new MethodChannel.Result() {
@Override
public void success(Object result) {
Map<String, Object> resultMap = (Map<String, Object>) result;
Log.i("FlutterplugindemoPlugin", "回参:map=" + resultMap.toString());
}
@Override
public void error(String errorCode, String errorMessage, Object errorDetails) {
}
@Override
public void notImplemented() {
}
});
} else {
result.notImplemented();
}
}
public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
}
}
2.2 flutter部分
初始化
_channel = MethodChannel('flutterplugindemo');
_channel.setMethodCallHandler(handler);
获取参数和返回结果
Future<dynamic> handler(MethodCall call) async {
if (call.method == "sayhello2") {
Map<dynamic, dynamic> map = call.arguments;
print(map);
Map<dynamic, dynamic> map2 = Map();
map2["param"] = "4444";
return map2;
}
}
示例
import 'dart:async';
import 'package:flutter/services.dart';
class Flutterplugindemo {
MethodChannel _channel;
Flutterplugindemo() {
init();
}
init() {
//调用原生的通道,"flutterplugindemo"要和原生部分一致
_channel = MethodChannel('flutterplugindemo');
_channel.setMethodCallHandler(handler);
}
Future<dynamic> handler(MethodCall call) async {
if (call.method == "sayhello2") {
Map<dynamic, dynamic> map = call.arguments;
print(map);
Map<dynamic, dynamic> map2 = Map();
map2["param"] = "4444";
return map2;
}
}
}
三、原生发送事件通知flutter
3.1 flutter部分
注册监听
//监听原生事件
EventChannel("flutter_plugin_event_2")
.receiveBroadcastStream()
.listen(eventListener);
接收事件
//接收事件
void eventListener(dynamic event) {
Map<dynamic, dynamic> map = event;
print("event" + map.toString());
}
示例
import 'dart:async';
import 'package:flutter/services.dart';
class Flutterplugindemo {
MethodChannel _channel;
Flutterplugindemo() {
init();
}
init() {
//监听原生事件,"flutter_plugin_event_2"要和原生部分一致
EventChannel("flutter_plugin_event_2")
.receiveBroadcastStream()
.listen(eventListener);
}
//接收事件
void eventListener(dynamic event) {
Map<dynamic, dynamic> map = event;
print("event" + map.toString());
}
}
3.2 原生部分
初始化
EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"flutter_plugin_event_2");
eventChannel.setStreamHandler(streamHandler);
private EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
eventSink = events;
}
@Override
public void onCancel(Object arguments) {
}
};
发送事件
//发送事件
if (eventSink != null) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("333", "44444");
eventSink.success(resultMap);
}
示例
package com.example.flutterplugindemo.demo;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class DemoPlugin implements MethodChannel.MethodCallHandler {
private EventChannel.EventSink eventSink;
public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"flutter_plugin_event_2");
eventChannel.setStreamHandler(streamHandler);
}
private EventChannel.StreamHandler streamHandler = new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
eventSink = events;
}
@Override
public void onCancel(Object arguments) {
}
};
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (call.method.equals("sendEvent")) {
//发送事件
if (eventSink != null) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("333", "44444");
eventSink.success(resultMap);
}
} else {
result.notImplemented();
}
}
public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
}
}
四、flutter使用原生view
主要使用AndroidView封装实现
4.1 flutter部分
初始化
if (defaultTargetPlatform == TargetPlatform.android) {
//原生页面
return AndroidView(
viewType: "nativeweb",
onPlatformViewCreated: onPlatformViewCreated,
creationParamsCodec: StandardMessageCodec(),
);
}
封装调用原生方法的controller
typedef void WebViewCreatedCallback(WebController controller);
//调用原生方法的Controller
class WebController {
MethodChannel _channel;
WebController.init(int id) {
_channel = MethodChannel("nativeweb_$id");
}
//调用原生方法
Future<void> loadUrl(String url) async {
assert(url != null);
await _channel.invokeMethod("loadUrl", url);
}
}
Future<void> onPlatformViewCreated(int id) async {
if (widget.onWebCreated == null) {
return;
}
widget.onWebCreated(WebController.init(id));
}
示例
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
typedef void WebViewCreatedCallback(WebController controller);
class NativeWeb extends StatefulWidget {
final WebViewCreatedCallback onWebCreated;
NativeWeb({this.onWebCreated});
@override
State<StatefulWidget> createState() => NativeWebState();
}
class NativeWebState extends State<NativeWeb> {
@override
Widget build(BuildContext context) {
if (defaultTargetPlatform == TargetPlatform.android) {
//原生页面
return AndroidView(
viewType: "nativeweb",
onPlatformViewCreated: onPlatformViewCreated,
creationParamsCodec: StandardMessageCodec(),
);
} else {
return Text("$defaultTargetPlatform 不支持此插件");
}
}
Future<void> onPlatformViewCreated(int id) async {
if (widget.onWebCreated == null) {
return;
}
widget.onWebCreated(WebController.init(id));
}
}
//调用原生方法的Controller
class WebController {
MethodChannel _channel;
WebController.init(int id) {
_channel = MethodChannel("nativeweb_$id");
}
//调用原生方法
Future<void> loadUrl(String url) async {
assert(url != null);
await _channel.invokeMethod("loadUrl", url);
}
}
4.2 原生部分
初始化
创建PlatformViewFactory、PlatformView
public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) {
binding.getPlatformViewRegistry()
.registerViewFactory("nativeweb", new WebFactory(binding));
}
private FlutterPlugin.FlutterPluginBinding flutterPluginBinding;
public WebFactory(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
super(StandardMessageCodec.INSTANCE);
this.flutterPluginBinding = flutterPluginBinding;
}
@Override
public PlatformView create(Context context, int viewId, Object args) {
return new FlutterWeb(context,flutterPluginBinding,viewId);
}
创建view
在FlutterWeb.java中。
/**
* 创建view
* @return
*/
@Override
public View getView() {
return webView;
}
封装调用方法
channel = new MethodChannel(binding.getBinaryMessenger(),"nativeweb_"+id);
channel.setMethodCallHandler(this);
/**
* 调用方法
* @param call
* @param result
*/
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method){
case "loadUrl":
String url = call.arguments.toString();
webView.loadUrl(url);
break;
default:
result.notImplemented();
}
}
示例
WebViewPlugin.java
package com.example.flutterplugindemo.webview;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
public class WebViewPlugin {
public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) {
binding.getPlatformViewRegistry()
.registerViewFactory("nativeweb", new WebFactory(binding));
}
public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) {
}
}
WebFactory.java
package com.example.flutterplugindemo.webview;
import android.content.Context;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class WebFactory extends PlatformViewFactory {
private FlutterPlugin.FlutterPluginBinding flutterPluginBinding;
public WebFactory(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
super(StandardMessageCodec.INSTANCE);
this.flutterPluginBinding = flutterPluginBinding;
}
@Override
public PlatformView create(Context context, int viewId, Object args) {
return new FlutterWeb(context,flutterPluginBinding,viewId);
}
}
FlutterWeb.java
package com.example.flutterplugindemo.webview;
import android.content.Context;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
public class FlutterWeb implements PlatformView , MethodChannel.MethodCallHandler{
Context context;
MethodChannel channel;
WebView webView;
public FlutterWeb(Context context,FlutterPlugin.FlutterPluginBinding binding, int id) {
this.context = context;
webView = getWebView(binding.getApplicationContext());
channel = new MethodChannel(binding.getBinaryMessenger(),"nativeweb_"+id);
channel.setMethodCallHandler(this);
}
/**
* 创建view
* @return
*/
@Override
public View getView() {
return webView;
}
@Override
public void dispose() {
}
/**
* 调用方法
* @param call
* @param result
*/
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method){
case "loadUrl":
String url = call.arguments.toString();
webView.loadUrl(url);
break;
default:
result.notImplemented();
}
}
private WebView getWebView(Context context){
WebView webView = new WebView(context);
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
return webView;
}
}
4.3 使用
布局中直接使用即可
NativeWeb(onWebCreated: onWebCreated)
示例:
import 'package:flutter/material.dart';
import 'package:flutterplugindemo/flutter_plugin_webview.dart';
import 'package:flutterplugindemo/flutterplugindemo.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Flutterplugindemo flutterplugindemo;
@override
void initState() {
super.initState();
flutterplugindemo = Flutterplugindemo();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: <Widget>[
Container(
height: 500,
child: NativeWeb(onWebCreated: onWebCreated),
),
],
),
),
);
}
void onWebCreated(WebController webController) {
webController.loadUrl("https://www.baidu.com/");
}
}