用Flutter開(kāi)發(fā)自定義Plugin的方法示例
當(dāng)你在開(kāi)發(fā)flutter應(yīng)用的時(shí)候,有時(shí)會(huì)需要調(diào)用native的api,往往遇到flutter并沒(méi)有相應(yīng)的package, 這時(shí)候flutter plugin就開(kāi)始發(fā)揮作用了,這篇文章將會(huì)講解開(kāi)發(fā)一個(gè)簡(jiǎn)單flutter plugin的步驟和方法,好了,讓我們開(kāi)始動(dòng)手吧。
1.在Android Studio 中創(chuàng)建一個(gè)Flutter Plugin 項(xiàng)目,如下圖
上圖中你能看到項(xiàng)目描述中寫到,如果需要暴露Andorid或iOS的API給開(kāi)發(fā)者時(shí),選擇"Plugin"項(xiàng)目類型。
這個(gè)項(xiàng)目我們命名為:flutter_native_log_plugin, 當(dāng)我們完成創(chuàng)建項(xiàng)目后,有兩個(gè)文件我們需要看一看, 一個(gè)是位于android/src下的FlutterNativeLogPlugin.java, 這段代碼是用來(lái)和本地設(shè)備交互,然后將交互結(jié)果返回供flutter前端調(diào)用, 如下所示:
package com.cube8.flutter_native_log_plugin; 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; /** FlutterNativeLogPlugin */ public class FlutterNativeLogPlugin implements MethodCallHandler { /** Plugin registration. */ public static void registerWith(Registrar registrar) { final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_native_log_plugin"); channel.setMethodCallHandler(new FlutterNativeLogPlugin()); } @Override public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("getPlatformVersion")) { result.success("Android " + android.os.Build.VERSION.RELEASE); } else { result.notImplemented(); } } }
另一個(gè) /lib/mian.dart文件,這段代碼是主要用來(lái)和native代碼交互, 如下所示:
import 'dart:async'; import 'package:flutter/services.dart'; class FlutterNativeLogPlugin { static const MethodChannel _channel = const MethodChannel('flutter_native_log_plugin'); static Future<String> get platformVersion async { final String version = await _channel.invokeMethod('getPlatformVersion'); return version; } }
2.現(xiàn)在我們開(kāi)始編寫我們的Plugin.
在lib/flutter_native_log_plugin.dart 文件中,我們先創(chuàng)建一個(gè)新的方法,代碼如下:
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; enum Log { DEBUG, WARNING, ERROR } class FlutterNativeLogPlugin { static const MethodChannel _channel = const MethodChannel('flutter_native_log_plugin'); static Future<String> printLog( {Log logType, @required String tag, @required String msg}) async { String log = "debug"; if (logType == Log.WARNING) { log = "warning"; } else if (logType == Log.ERROR) { log = "error"; } else { log = "debug"; } final Map<String, dynamic> params = <String, dynamic>{ 'tag': tag, 'msg': msg, 'logType': log }; final String result = await _channel.invokeMethod('printLog', params); return result; } }
在Android端,我們將android/src下的FlutterNativePlugin.java改寫如下:
package com.cube8.flutter_native_log_plugin; import android.util.Log; 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; /** * FlutterNativeLogPlugin */ public class FlutterNativeLogPlugin implements MethodCallHandler { /** * Plugin registration. */ public static void registerWith(Registrar registrar) { final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_native_log_plugin"); channel.setMethodCallHandler(new FlutterNativeLogPlugin()); } @Override public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("printLog")) { String msg = call.argument("msg"); String tag = call.argument("tag"); String logType = call.argument("logType"); if (logType.equals("warning")) { Log.w(tag, msg); } else if (logType.equals("error")) { Log.e(tag, msg); } else { Log.d(tag, msg); } result.success("Logged Successfully!"); } else { result.notImplemented(); } } }
3.測(cè)試plugin。當(dāng)開(kāi)發(fā)完了我們的plugin之后,我們需要測(cè)試這個(gè)新plugin是否可用,于是對(duì)example/lib的main.dart文件作如下修改:
import 'package:flutter/material.dart'; import 'package:flutter_native_log_plugin/flutter_native_log_plugin.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override void initState() { super.initState(); } void printLogs() async { print(await FlutterNativeLogPlugin.printLog( tag: "Debug", msg: "This is ordinary Log")); // default logType print(await FlutterNativeLogPlugin.printLog( tag: "Debug", msg: "This is warning Log", logType: Log.WARNING)); // logType = warning print(await FlutterNativeLogPlugin.printLog( tag: "Debug", msg: "This is error Log", logType: Log.ERROR)); // logType = error print(await FlutterNativeLogPlugin.printLog( tag: "Debug", msg: "This is debug Log", logType: Log.DEBUG)); // logType = debug } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin example app'), ), body: Center( child: RaisedButton( child: Text("PrintLogs"), onPressed: printLogs, ), ), ), ); } }
點(diǎn)擊app中的按鈕,控制臺(tái)將看到如下輸出,說(shuō)明plugin可以順利運(yùn)行了。
4.最后一步就是將我們開(kāi)發(fā)的plugin發(fā)布到dart pub供以后直接調(diào)用。打開(kāi)控制臺(tái),需要確認(rèn)定位到plugin項(xiàng)目的根目錄,然后輸入如下命令:
flutter packages pub publish --dry-run
這段命令會(huì)做一個(gè)程序相關(guān)文件和信息的檢查,確保待發(fā)布的plugin信息完整,根據(jù)控制臺(tái)的提示完善信息后,與下圖相似:
接著輸入如下命令,正式將plugin發(fā)布到dart pub中:
flutter packages pub publish
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- flutter實(shí)現(xiàn)仿boss直聘功能
- Flutter實(shí)現(xiàn)頁(yè)面切換后保持原頁(yè)面狀態(tài)的3種方法
- Flutter質(zhì)感設(shè)計(jì)之彈出菜單
- Flutter實(shí)現(xiàn)底部導(dǎo)航欄效果
- Flutter實(shí)戰(zhàn)之自定義日志打印組件詳解
- Flutter質(zhì)感設(shè)計(jì)之進(jìn)度條
- Flutter 網(wǎng)絡(luò)請(qǐng)求框架封裝詳解
- Flutter中獲取屏幕及Widget的寬高示例代碼
- Flutter中網(wǎng)絡(luò)圖片加載和緩存的實(shí)現(xiàn)
- Flutter質(zhì)感設(shè)計(jì)之持久底部面板
相關(guān)文章
android push推送相關(guān)基本問(wèn)答總結(jié)
現(xiàn)在網(wǎng)上一大堆的關(guān)于推送方面的實(shí)現(xiàn)原理:1.通過(guò)pull(拉),也就是通過(guò)客戶端主動(dòng)定時(shí)輪詢服務(wù)器請(qǐng)求數(shù)據(jù)。2.通過(guò)push(推),服務(wù)器通過(guò)一個(gè)長(zhǎng)連接主動(dòng)推送消息到客戶端。這兩個(gè)方式都可以實(shí)現(xiàn)推送功能。pull這個(gè)方式?jīng)]什么問(wèn)題好理解。2015-05-05android 仿微信demo——微信啟動(dòng)界面實(shí)現(xiàn)
本篇文章主要介紹了微信小程序-閱讀小程序?qū)嵗╠emo),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望能給你們提供幫助2021-06-06android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼
這篇文章主要介紹了android 監(jiān)聽(tīng)SD卡文件變化的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-11-11Android開(kāi)發(fā)SavedState?Jetpack狀態(tài)保存利器
這篇文章主要為大家介紹了Android開(kāi)發(fā)SavedState?Jetpack狀態(tài)保存利器使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Flutter實(shí)現(xiàn)紅包動(dòng)畫效果的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Flutter實(shí)現(xiàn)紅包的動(dòng)畫效果,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下2023-06-06Android自定義View實(shí)現(xiàn)波浪動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)波浪動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08Android Jetpack Compose實(shí)現(xiàn)列表吸頂效果
安卓傳統(tǒng)的Recyclerview打造懸浮頭部StickyHeader的吸頂效果,十分麻煩,而在Compose中就簡(jiǎn)單多了。因此,本文將采用Jetpack Compose實(shí)現(xiàn)列表吸頂效果,需要的可以參考一下2022-02-02Android文本框搜索和清空效果實(shí)現(xiàn)代碼及簡(jiǎn)要概述
在工作過(guò)程中可能會(huì)遇到這樣一個(gè)效果:文本框輸入為空時(shí)顯示輸入的圖標(biāo);不為空時(shí)顯示清空的圖標(biāo),此時(shí)點(diǎn)擊清空?qǐng)D標(biāo)能清空文本框內(nèi)輸入文字,感興趣的你可以了解下哦,或許對(duì)你學(xué)習(xí)android有所幫助2013-02-02Android開(kāi)發(fā)之圖形圖像與動(dòng)畫(三)Animation效果的XML實(shí)現(xiàn)
使用XML來(lái)定義Tween Animation動(dòng)畫的XML文件在工程中res/anim目錄,這個(gè)文件必須包含一個(gè)根元素,感興趣的友可以了解一下,希望本文對(duì)你有所幫助2013-01-01