上次从一个路径插件看来一下Flutter中如何调用iOS和Android中的方法以及平台如何返回值给Flutter框架。今天就来详细讲讲MethodChannel是如何连同另一个世界的。
1.从吐司弹框开始说起(Android端/Java)
想要达成的效果是这样使用可以弹出一个时间较长的吐司
这个示例要讲述的是Flutter中如何向平台传递参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNH1nR59-1629539325555)(https://user-gold-cdn.xitu.io/2019/8/12/16c83c52b7e9c7c4?imageView2/0/w/1280/h/960/ignore-error/1)]
var show = RaisedButton(
onPressed: () {
IaToast.show(msg: "hello",type: Toast.LENGTH_LONG);
},
child: Text("点击弹吐司"),
);
1.1.Flutter/Dart端
定义一个
IaToast
的吐司类,根据枚举类型使用MethodChannel调用原生方法
import 'package:flutter/services.dart';
///吐司类型 [LENGTH_SHORT]短时间,[LENGTH_LONG]长时间
enum Toast {
LENGTH_SHORT,
LENGTH_LONG
}
///吐司类
class IaToast {
static const MethodChannel _channel =//方法渠道名
const MethodChannel('www.toly1994.com.flutter_journey.toast');
static show(//静态方法显示吐司
{String msg, Toast type = Toast.LENGTH_SHORT}) {
if (type == Toast.LENGTH_SHORT) {
_channel.invokeMethod('showToast', {//渠道对象调用方法
"msg": msg,
"type": 0,
});
} else {
_channel.invokeMethod('showToast', {
"msg": msg,
"type": 1,
});
}
}
}
1.2:Android/Java端
通过FlutterView和渠道名可以获取MethodChannel对象,对其进行方法调用监听
其中的两个回调参数分别储存着方法信息和返回信息。
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "www.toly1994.com.flutter_journey.toast";//渠道名
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
MethodChannel channel = new MethodChannel(getFlutterView(), CHANNEL);//获取渠道
channel.setMethodCallHandler(this::handleMethod);//设置方法监听
}
/**
* 处理方法回调监听
* @param methodCall 方法的参数相关
* @param result 方法的返回值相关
*/
private void handleMethod(MethodCall methodCall, MethodChannel.Result result) {
switch (methodCall.method){//根据方法名进行处理
case "showToast":
handleToast(this,methodCall);//具体处理
break;
default:
result.notImplemented();
}
}
public static void handleToast(Context context,MethodCall methodCall) {
String msg=methodCall.argument("msg");
int type=methodCall.argument("type");
Toast.makeText(context, msg, type).show();
}
}
1.3:使用效果
这样对应Android端,在Flutter中就可以开心的弹吐司了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOg5nhNn-1629539325557)(https://user-gold-cdn.xitu.io/2019/8/12/16c83e575e5f1135?imageView2/0/w/1280/h/960/ignore-error/1)]
var show = RaisedButton(
onPressed: () {
IaToast.show(msg: "hello Flutter", type: Toast.LENGTH_LONG);//使用吐司
},
child: Text("点击弹吐司"),
);
var app = MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Flutter之旅'),
),
body: show,
),
);
void main() => runApp(app);
2.从吐司弹框开始说起(iOS端/Swift)
也简单的画了一幅Flutter和iOS沟通的图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZbBFwoL-1629539325558)(https://user-gold-cdn.xitu.io/2019/8/12/16c8490f881aece8?imageView2/0/w/1280/h/960/ignore-error/1)]
2.1:创建插件类:
现在来看iOS端如何接受Flutter中的参数,和Android中基本一致,首先要获得渠道
在iOS里FlutterMethodChannel通过渠道标识和FlutterViewController来获取。
有了渠道方法之后,剩下的就几乎一致了,只是语法问题。
通过FlutterMethodCall回调中的call中的arguments值来获取参数,强转成NSDictionary
不过iOS系统并没有直接弹吐司的方法,所以需要自定义吐司。
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
public static let channelId="www.toly1994.com.flutter_journey.toast"
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller:FlutterViewController = window.rootViewController as! FlutterViewController
let messageChannel = FlutterMethodChannel.init(//获取方法渠道
name: AppDelegate.channelId,
binaryMessenger:controller)
messageChannel.setMethodCallHandler{(call, result) in
self.handle(call,result)
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
public func handle(_ call: FlutterMethodCall,_ result: @escaping FlutterResult) {
let args: NSDictionary = call.arguments as! NSDictionary
switch call.method {
case "showToast":
let msg:String = args["msg"] as! String
let type:Int = args["type"] as! Int
handleToast(msg:msg,type:type)
default:
result(FlutterMethodNotImplemented)
}
}
public func handleToast(msg: String, type: Int) {
Toast.toast(text: msg,type:type)
}
}
2.2:自定义吐司
使用UILabel和UIButton进行模拟一个吐司