Flutter 只是一个 UI 框架,对于一些系统调用或者各自平台的的特有实现需要开发者自行编写 package,通过在 package 内实现不同平台的调用方式,以这样的方式进行适配.今天记录下怎样在不同平台编写 package.由于自己不会 iOS,所以只是实现一个简单的 Android Toast.iOS 端使用定时的UIAlertView去模拟.
新建 package
我的工具是 Android Studio,首先在项目根目录下new->module->选择 Fullter package,点击 next,然后看到这个界面修改报名和描述,并且选择自己的 Flutter SDK 目录,最后点击 finish.一个新的 package 就新建完成了.当然如果使用 VSCode 的话也可以使用命令行新建 package.
package目录如下图所示
Android 端实现,即在这这里编写原生调用代码
1 | public class FlutterToastPlugin implements MethodCallHandler { |
package 项目入口,我们可以在这里调用本身实现的功能,选择此文件 run 及时查看效果
1 | import 'dart:async'; |
iOS 端实现 由于自己不会 Object-C 所以代码很简单,很容易看懂
{% codeblock lang:objc %}
#import “FlutterToastPlugin.h”
@implementation FlutterToastPlugin
- (void)registerWithRegistrar:(NSObject
)registrar {
FlutterMethodChannel channel = [FlutterMethodChannel
methodChannelWithName:@”flutter_toast”
binaryMessenger:[registrar messenger]];
FlutterToastPlugin* instance = [[FlutterToastPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@”getPlatformVersion” isEqualToString:call.method]) {
//默认实现
result([@”iOS “ stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
}else if([@”showToast” isEqualToString:call.method]) {//判断调用方法名
//获取调用参数
NSString *msg = call.arguments[@”message”];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:nil
message:msg
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil, nil];
[alert show];
double duration = 0.5;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[alert dismissWithClickedButtonIndex:0 animated:YES];
});
}else if([@”showLongToast” isEqualToString:call.method]) {
NSString *msg = call.arguments[@”message”];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:nil
message:msg
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil, nil];
[alert show];
double duration = 1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[alert dismissWithClickedButtonIndex:0 animated:YES];
});
}else {
result(FlutterMethodNotImplemented);
}
}
@end
{% endcodeblock %}
若第一次把 package 运行在 iOS 端会提示错误,按照提示依次执行 brew install cocoapods
和 pod setup
,等待安装完成后,再次运行就可以在模拟器查看效果了.
Flutter 桥接代码实现
1 | import 'dart:async'; |
总结
Flutter 插件编写逻辑还是很简单,具体的实现方式还没有具体研究,有时间需要大概理解原理,这样也又便于编程思维的开拓.通过这个 demo,熟悉了插件编写方式,对于一些 Flutter 不支持的功能就可以让原生实现,比如嵌入WebView就可以通过原生提供实现.
GitHub地址
在线编写Flutter实时预览