Flutter中嵌入Android 原生TextView實例教程
前言
本篇文章 中寫到的是 flutter 調(diào)用了Android 原生的 TextView 案例
添加原生組件的流程基本上可以描述為:
1 android 端實現(xiàn)原生組件PlatformView提供原生view
2 android 端創(chuàng)建PlatformViewFactory用于生成PlatformView
3 android 端創(chuàng)建FlutterPlugin用于注冊原生組件
4 flutter 平臺嵌入 原生view
1 創(chuàng)建原生組件
創(chuàng)建在fLutter工程時會生成幾個文件夾,lib是放flutter工程代碼,android和ios文件夾分別是對應(yīng)的雙平臺的原生工程。
在這里直接打開Android工程目錄,項目默認(rèn)生成了GeneratedPluginRegistrant和MainActivity兩個文件,GeneratedPluginRegistrant不要動,GeneratedPluginRegistrant是flutter中配制使用其他插件時,程序在編譯時自動進行插件注冊使用的類。
在MainActivity的包下新建自定義View,F(xiàn)lutter的原生View不能直接繼承自View,需要實現(xiàn)提供的PlatformView接口:
public class TestTextView implements PlatformView r{ private final TextView mTestTextView; /** * * @param context * @param messenger * @param id * @param params 初始化時 flutter 傳遞過來的參數(shù) */ TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) { //創(chuàng)建 TextView TextView lTextView = new TextView(context); lTextView.setText("Android的原生TextView"); this.mTestTextView = lTextView; //flutter 傳遞過來的參數(shù) if (params!=null&¶ms.containsKey("content")) { String myContent = (String) params.get("content"); lTextView.setText(myContent); } } @Override public View getView() { return mTestTextView; } @Override public void dispose() { } }
2 創(chuàng)建PlatformViewFactory
import android.content.Context; import java.util.Map; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; public class TestViewFactory extends PlatformViewFactory { private final BinaryMessenger messenger; public TestViewFactory(BinaryMessenger messenger) { super(StandardMessageCodec.INSTANCE); this.messenger = messenger; } /** * * @param context * @param id * @param args args是由Flutter傳過來的自定義參數(shù) * @return */ @SuppressWarnings("unchecked") @Override public PlatformView create(Context context, int id, Object args) { //flutter 傳遞過來的參數(shù) Map<String, Object> params = (Map<String, Object>) args; //創(chuàng)建 TestTextView return new TestTextView(context, messenger, id, params); }
3 創(chuàng)建Plugin并在ManActivity中注冊插件
/** * flutter 調(diào)用 android 原生view * */ public class TestFluttertoAndroidTextViewPlugin { public static void registerWith(PluginRegistry registry) { //防止多次注冊 final String key = TestFluttertoAndroidTextViewPlugin.class.getCanonicalName(); if (registry.hasPlugin(key)) return; //初始化 PluginRegistry PluginRegistry.Registrar registrar = registry.registrarFor(key); //設(shè)置標(biāo)識 registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger())); } }
MainActivity 中注冊
import android.os.Bundle import io.flutter.app.FlutterActivity import io.flutter.plugins.FlutterToAndroidPlugins import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //flutter 項目工程中默認(rèn)生成的 GeneratedPluginRegistrant.registerWith(this) //這是我們新創(chuàng)建的插件 TestFluttertoAndroidTextViewPlugin.registerWith(this) } override fun onDestroy() { super.onDestroy() } }
4 flutter頁面中嵌入android 原生Textview
4.1 最簡單的調(diào)用
//這里設(shè)置的 viewType值與 android 中插件注冊的標(biāo)識 一至 //registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger())); mTextWidget = Container( height: 200, child: AndroidView( //設(shè)置標(biāo)識 viewType: "com.flutter_to_native_test_textview", ), ); @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: appBar, //顯示的頁面 body: mTextWidget, ); }
4.2 flutter 調(diào)用 原生view并傳參數(shù)
mTextWidget = Container( height: 200, child: AndroidView( //標(biāo)識 viewType: "com.flutter_to_native_test_textview", creationParams: { "content": "flutter 傳入的文本內(nèi)容", }, //參數(shù)的編碼方式 creationParamsCodec: const StandardMessageCodec(), ), );
android 原生中的接收(只會接收一次)
... ... TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) { ... .. //flutter 傳遞過來的參數(shù) if (params!=null&&!params.isEmpty()&¶ms.containsKey("content")) { String myContent = (String) params.get("content"); lTextView.setText(myContent); } ... ... }
4.3 flutter 更新 原生view 中的數(shù)據(jù)
原生組件初始化的參數(shù)并不會隨著setState重復(fù)賦值,可以通過MethodCall來實現(xiàn)更新數(shù)據(jù)。
首先讓原生view組件實現(xiàn)MethodCallHandler接口:
public class TestTextView implements PlatformView , MethodChannel.MethodCallHandler{ private final TextView mTestTextView; TestTextView(Context context, BinaryMessenger messenger, int id, Map<String, Object> params) { ... ... //com.flutter_to_native_test_view_ 是更新數(shù)據(jù)的通信標(biāo)識 MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id); methodChannel.setMethodCallHandler(this); } ... ... @Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { //updateText 是flutter 中調(diào)用的方法名稱,可以隨意定義 if ("updateText".equals(methodCall.method)) { String text = (String) methodCall.arguments; this.mTestTextView .setText(text); //對flutter 的回調(diào) result.success(null); } } }
flutter 中調(diào)用 android 原生view
MethodChannel _channel; int viewId=0;
mTextWidget = Container( height: 200, child: AndroidView( //標(biāo)識 viewType: "com.flutter_to_native_test_textview", creationParams: { "content": "flutter 傳入的文本內(nèi)容", }, //參數(shù)的編碼方式 creationParamsCodec: const StandardMessageCodec(), //view創(chuàng)建完成時的回調(diào) onPlatformViewCreated: (id) { viewId = id; }, ), );
更新數(shù)據(jù)
//這里設(shè)置的標(biāo)識 MethodChannel('com.flutter_to_native_test_textview_$viewId'); // 與android MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id); 中注冊的一至 void clickUpdtae(){ _channel = new MethodChannel('com.flutter_to_native_test_textview_$viewId'); updateTextView(); } //這里的標(biāo)識 updateText //與android 中接收消息的方法中 //if ("updateText".equals(methodCall.method)) {...} 一至 void updateTextView() async { return _channel.invokeMethod('updateText', "更新內(nèi)容"); }
通過onPlatformViewCreated回調(diào),監(jiān)聽原始組件成功創(chuàng)建,并能夠在回調(diào)方法的參數(shù)中拿到當(dāng)前組件的id,這個id是系統(tǒng)隨機分配的,然后通過這個分配的id加上我們的組件名稱最為前綴創(chuàng)建一個和組件通訊的MethodChannel,拿到channel對象之后就可以通過invokeMethod方法向原生組件發(fā)送消息了,這里這里調(diào)用的是‘updateText'這個方法,參數(shù)是一個String
總結(jié)
到此這篇關(guān)于Flutter中嵌入Android 原生TextView實例教程的文章就介紹到這了,更多相關(guān)Flutter嵌入Android 原生TextView內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題
今天小編就為大家分享一篇關(guān)于Android解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12Android中Handler實現(xiàn)倒計時的兩種方式
本篇文章主要介紹了Android中Handler實現(xiàn)倒計時的兩種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07Android開發(fā)中WebView的簡單使用小結(jié)
WebView(網(wǎng)絡(luò)視圖)能加載顯示網(wǎng)頁,可以將其視為一個瀏覽器。它使用了WebKit渲染引擎加載顯示網(wǎng)頁。下面這篇文章給大家總結(jié)了Android中WebView的簡單使用,有需要的可以參考借鑒。2016-09-09Android TextView實現(xiàn)垂直滾動效果的方法
這篇文章主要介紹了Android TextView實現(xiàn)垂直滾動效果的方法,結(jié)合實例形式簡單分析了Android TextView控件垂直滾動效果的相關(guān)屬性功能與設(shè)置技巧,需要的朋友可以參考下2016-10-10解決Android Studio sdk emulator directory is missing問題
這篇文章主要介紹了解決Android Studio sdk emulator directory is missing問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11