Flutter 1.9.1java
AndroidStudio 3.5.3android
新建一个 名为 flutter_plugin_demo 的 Flutter 工程,如下称为主工程。ios
右键工程名,新建一个名为 flutter_plugin 的 Moudle ,所选模块为 Flutter Plugin,其间你能够根据选择依赖插件所支持的 Kotlin 或者是 Swift 语言。git
建立完 Plugin 以后,flutter_plugin 会自动建立一个 example 的 Flutter 项目,由于 example 下面 test 包下面的 MyApp 类名会和主工程的类名冲突,因此替换如下便可。github
右键 example/lib/main.dart,Run main.dart。若是在 IOS 模拟器中 build 成功可是包以下错误:markdown
The application's Info.plist does not contain CFBundleVersion.
复制代码
则在 example/pubspec.yaml 中添加app
version: 1.0.0+1
复制代码
再次运行便可。less
这说明其实插件自己已经帮咱们实现了获取运行平台的功能,下面以简单的实现 toast 功能。async
用 AndroidStudio File/Open, 打开 flutter_plugin 工程:ide
除此以外,还能够选中 android 文件夹,右键点击,找到 Flutter,Open Android module in Android Studio,以下图,由于有时候我用这种方式打开以后编写代码没有 API 提示,就各类尝试,看我的了,迷之正确。
package com.hcl.flutter_plugin;
import android.util.Log;
import android.widget.Toast;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** FlutterPlugin */
public class FlutterPlugin implements MethodCallHandler {
private static final String TAG = FlutterPlugin.class.getSimpleName();
private final Registrar registrar;
//构造
private FlutterPlugin(Registrar registrar) {
this.registrar = registrar;
}
/** * Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_plugin");
channel.setMethodCallHandler(new FlutterPlugin(registrar));
}
//来自Flutter的方法调用
@Override
public void onMethodCall(MethodCall call, Result result) {
String target = call.method;
switch (target) {
case "getPlatformVersion":
result.success("Android " + android.os.Build.VERSION.RELEASE);
break;
case "toast":
String content = (String) call.arguments;
Log.d(TAG, "toast: " + content);
showToast(content);
break;
default:
result.notImplemented();
break;
}
}
/** * 显示Toast * * @param content */
private void showToast(String content) {
Toast.makeText(registrar.context(), content, Toast.LENGTH_SHORT).show();
}
}
复制代码
import 'dart:async';
import 'package:flutter/services.dart';
class FlutterPlugin {
//除了 MethodChannel 还有其余交互方式
static const MethodChannel _channel =
const MethodChannel('flutter_plugin');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
/** * 显示Toast */
static Future<void> showToast(String content)async {
await _channel.invokeMethod("toast",content);
}
}
复制代码
FlutterAndroidPlugin.showToast("Hello World");
复制代码
这里只实现了 Android 部分的代码,因此只能运行到 Android 模拟器。
用 XCode 打开 Xcode 打开 example 工程中 iOS 项目,找到 ios 目录下的 Runner.xcworkspace。找到 FlutterPlugin.m 文件,目录结构以下:
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
NSString* methodName=call.method;
NSString * params = call.arguments;
if ([@"getPlatformVersion" isEqualToString:methodName]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else if([@"toast" isEqualToString:methodName ]){
[self showMessage:params duration:2];
}else{
result(FlutterMethodNotImplemented);
}
}
复制代码
再添加方法:
//Toast
-(void)showMessage:(NSString *)message duration:(NSTimeInterval)time
{
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
UIWindow * window = [UIApplication sharedApplication].keyWindow;
UIView *showview = [[UIView alloc]init];
showview.backgroundColor = [UIColor grayColor];
showview.frame = CGRectMake(1, 1, 1, 1);
showview.alpha = 1.0f;
showview.layer.cornerRadius = 5.0f;
showview.layer.masksToBounds = YES;
[window addSubview:showview];
UILabel *label = [[UILabel alloc]init];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:15.f],
NSParagraphStyleAttributeName:paragraphStyle.copy};
CGSize labelSize = [message boundingRectWithSize:CGSizeMake(207, 999)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes context:nil].size;
label.frame = CGRectMake(10, 5, labelSize.width +20, labelSize.height);
label.text = message;
label.textColor = [UIColor whiteColor];
label.textAlignment = 1;
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:15];
[showview addSubview:label];
showview.frame = CGRectMake((screenSize.width - labelSize.width - 20)/2,
screenSize.height - 100,
labelSize.width+40,
labelSize.height+10);
[UIView animateWithDuration:time animations:^{
showview.alpha = 0;
} completion:^(BOOL finished) {
[showview removeFromSuperview];
}];
}
复制代码
便可。运行测试:
这里只说本地引用,以前测试的都是在插件的 example/main.dart 中进行的,如今若是要让要主工程也引用该插件,则只需在主工程的 pubspec.yaml 中添加依赖:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_plugin:
path: flutter_plugin #这个路径根据你插件的路径填写
复制代码
import 'package:flutter/material.dart';
import 'package:flutter_plugin/flutter_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Main"),
),
body: Center(
child: RaisedButton(
onPressed: () {
FlutterPlugin.showToast("Say Hello");
},
child: Text("Say Hello"),
),
),
);
}
}
复制代码