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解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題
今天小編就為大家分享一篇關(guān)于Android解決ScrollView下嵌套ListView和GridView中內(nèi)容顯示不全的問題,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Android中Handler實(shí)現(xiàn)倒計(jì)時(shí)的兩種方式
本篇文章主要介紹了Android中Handler實(shí)現(xiàn)倒計(jì)時(shí)的兩種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
Android開發(fā)中WebView的簡單使用小結(jié)
WebView(網(wǎng)絡(luò)視圖)能加載顯示網(wǎng)頁,可以將其視為一個(gè)瀏覽器。它使用了WebKit渲染引擎加載顯示網(wǎng)頁。下面這篇文章給大家總結(jié)了Android中WebView的簡單使用,有需要的可以參考借鑒。2016-09-09
Android TextView實(shí)現(xiàn)垂直滾動(dòng)效果的方法
這篇文章主要介紹了Android TextView實(shí)現(xiàn)垂直滾動(dòng)效果的方法,結(jié)合實(shí)例形式簡單分析了Android TextView控件垂直滾動(dòng)效果的相關(guān)屬性功能與設(shè)置技巧,需要的朋友可以參考下2016-10-10
Android實(shí)現(xiàn)圖片文字識(shí)別
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片文字識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
解決Android Studio sdk emulator directory is missing問題
這篇文章主要介紹了解決Android Studio sdk emulator directory is missing問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

