Flutter中嵌入Android 原生TextView實(shí)例教程
前言
本篇文章 中寫到的是 flutter 調(diào)用了Android 原生的 TextView 案例
添加原生組件的流程基本上可以描述為:
1 android 端實(shí)現(xiàn)原生組件PlatformView提供原生view
2 android 端創(chuàng)建PlatformViewFactory用于生成PlatformView
3 android 端創(chuàng)建FlutterPlugin用于注冊(cè)原生組件
4 flutter 平臺(tái)嵌入 原生view
1 創(chuàng)建原生組件
創(chuàng)建在fLutter工程時(shí)會(huì)生成幾個(gè)文件夾,lib是放flutter工程代碼,android和ios文件夾分別是對(duì)應(yīng)的雙平臺(tái)的原生工程。
在這里直接打開Android工程目錄,項(xiàng)目默認(rèn)生成了GeneratedPluginRegistrant和MainActivity兩個(gè)文件,GeneratedPluginRegistrant不要?jiǎng)?,GeneratedPluginRegistrant是flutter中配制使用其他插件時(shí),程序在編譯時(shí)自動(dòng)進(jìn)行插件注冊(cè)使用的類。
在MainActivity的包下新建自定義View,F(xiàn)lutter的原生View不能直接繼承自View,需要實(shí)現(xiàn)提供的PlatformView接口:
public class TestTextView implements PlatformView r{
private final TextView mTestTextView;
/**
*
* @param context
* @param messenger
* @param id
* @param params 初始化時(shí) 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中注冊(cè)插件
/**
* flutter 調(diào)用 android 原生view
*
*/
public class TestFluttertoAndroidTextViewPlugin {
public static void registerWith(PluginRegistry registry) {
//防止多次注冊(cè)
final String key = TestFluttertoAndroidTextViewPlugin.class.getCanonicalName();
if (registry.hasPlugin(key)) return;
//初始化 PluginRegistry
PluginRegistry.Registrar registrar = registry.registrarFor(key);
//設(shè)置標(biāo)識(shí)
registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
}
}
MainActivity 中注冊(cè)
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 項(xiàng)目工程中默認(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 中插件注冊(cè)的標(biāo)識(shí) 一至
//registrar.platformViewRegistry().registerViewFactory("com.flutter_to_native_test_textview", new TestViewFactory(registrar.messenger()));
mTextWidget = Container(
height: 200,
child: AndroidView(
//設(shè)置標(biāo)識(shí)
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)識(shí)
viewType: "com.flutter_to_native_test_textview",
creationParams: {
"content": "flutter 傳入的文本內(nèi)容",
},
//參數(shù)的編碼方式
creationParamsCodec: const StandardMessageCodec(),
),
);
android 原生中的接收(只會(huì)接收一次)
... ...
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ù)并不會(huì)隨著setState重復(fù)賦值,可以通過MethodCall來實(shí)現(xiàn)更新數(shù)據(jù)。
首先讓原生view組件實(shí)現(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)識(shí)
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);
//對(duì)flutter 的回調(diào)
result.success(null);
}
}
}
flutter 中調(diào)用 android 原生view
MethodChannel _channel; int viewId=0;
mTextWidget = Container(
height: 200,
child: AndroidView(
//標(biāo)識(shí)
viewType: "com.flutter_to_native_test_textview",
creationParams: {
"content": "flutter 傳入的文本內(nèi)容",
},
//參數(shù)的編碼方式
creationParamsCodec: const StandardMessageCodec(),
//view創(chuàng)建完成時(shí)的回調(diào)
onPlatformViewCreated: (id) {
viewId = id;
},
),
);
更新數(shù)據(jù)
//這里設(shè)置的標(biāo)識(shí) MethodChannel('com.flutter_to_native_test_textview_$viewId');
// 與android MethodChannel methodChannel = new MethodChannel(messenger, "com.flutter_to_native_test_textview_" + id); 中注冊(cè)的一至
void clickUpdtae(){
_channel = new MethodChannel('com.flutter_to_native_test_textview_$viewId');
updateTextView();
}
//這里的標(biāo)識(shí) 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,這個(gè)id是系統(tǒng)隨機(jī)分配的,然后通過這個(gè)分配的id加上我們的組件名稱最為前綴創(chuàng)建一個(gè)和組件通訊的MethodChannel,拿到channel對(duì)象之后就可以通過invokeMethod方法向原生組件發(fā)送消息了,這里這里調(diào)用的是‘updateText'這個(gè)方法,參數(shù)是一個(gè)String
總結(jié)
到此這篇關(guān)于Flutter中嵌入Android 原生TextView實(shí)例教程的文章就介紹到這了,更多相關(guān)Flutter嵌入Android 原生TextView內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android Notification的多種用法總結(jié)
這篇文章主要介紹了Android Notification的多種用法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android ListView和Adapter數(shù)據(jù)適配器的簡單介紹
這篇文章主要介紹了Android ListView和Adapter數(shù)據(jù)適配器的簡單介紹,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
Android獲取實(shí)時(shí)連接熱點(diǎn)的設(shè)備IP
這篇文章主要介紹了Android獲取實(shí)時(shí)連接熱點(diǎn)的設(shè)備IP 的相關(guān)資料,文中給大家補(bǔ)充介紹了安卓獲取接入的Wifi熱點(diǎn)設(shè)備的Ip地址的代碼,需要的朋友可以參考下2018-01-01
AndroidStudio修改Code Style來格式化自定義標(biāo)簽的xml文件方式
這篇文章主要介紹了AndroidStudio修改Code Style來格式化自定義標(biāo)簽的xml文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android超詳細(xì)講解組件AdapterView的使用
AdapterView組件是一組重要的組件,AdapterView本身是一個(gè)抽象基類,它派生的子類在用法上十分相似,從AdapterView派生出的三個(gè)子類:AdsListView、AdsSpinner、AdapterViewAnimator,這3個(gè)子類依然是抽象的,實(shí)際運(yùn)用時(shí)需要它們的子類2022-03-03
Android用tabhost實(shí)現(xiàn) 界面切換,每個(gè)界面為一個(gè)獨(dú)立的activity操作
這篇文章主要介紹了Android用tabhost實(shí)現(xiàn) 界面切換,每個(gè)界面為一個(gè)獨(dú)立的activity操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
OpenGL Shader實(shí)現(xiàn)物件材料效果詳解
在一些主流app上有一些比較特殊的濾鏡效果,例如灰塵、塑料封面、光影效果等,這些其實(shí)是紋理疊加的效果。本文將用OpenGL Shader實(shí)現(xiàn)這些效果,需要的可以參考一下2022-02-02
Android TabLayout 實(shí)現(xiàn)底部Tab的示例代碼
本篇文章主要介紹了Android TabLayout 實(shí)現(xiàn)底部Tab的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01

