[-Flutter插件篇 -] 认识MethodChannel

上次从一个路径插件看来一下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进行模拟一个吐司

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值