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"),
),
),
);
}
}
複製代碼