flutter學習之嵌入原生View - android
highlight: androidstudio
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第26天,點選檢視活動詳情
- 本文主要介紹如何在 flutter中載入原生android的view,之前我們介紹了flutter載入iOS view。原理也是類似。
1. 建立android中view
我們是iOS開發,這裡簡單介紹下如何載入原生android的view,其流程和我們iOS view類似。
我們在android專案的建立一個測試view ```Dart package com.example.flutter_android_view import android.content.Context import android.view.View import android.widget.TextView import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.platform.PlatformView
class TestView(context: Context, messenger: BinaryMessenger, viewId: Int, args: Map
private val textView: TextView = TextView(context)
init {
textView.text = "這是一個Android View"
}
override fun getView(): View {
return textView
}
override fun dispose() {
TODO("Not yet implemented")
}
}
我們繼續建立`TestViewFactory`
Dart
import android.content.Context
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory
class TestViewFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
return TestView(context, messenger, viewId, args as Map<String, Any>?)
}
}
建立TestPlugin
Dart
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.PluginRegistry
class TestViewPlugin : FlutterPlugin {
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
val messenger: BinaryMessenger = binding.binaryMessenger
binding
.platformViewRegistry
.registerViewFactory(
"plugins.flutter.io/custom_platform_view", TestViewFactory(messenger))
}
companion object {
@JvmStatic
fun registerWith(registrar: PluginRegistry.Registrar) {
registrar
.platformViewRegistry()
.registerViewFactory(
"plugins.flutter.io/custom_platform_view",
TestViewFactory(registrar.messenger()))
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
}
}
在 **App 中 MainActivity** 中註冊:
Dart
package com.example.flutter_android_view
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity: FlutterActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) flutterEngine.plugins.add(TestViewPlugin()) } } ``` 最後的目錄結構
嵌入flutter
```Dart import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart';
class AndroidViewPage extends StatelessWidget { const AndroidViewPage({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { String? title = "androidView";
return Scaffold(
appBar: AppBar(title: Text(title ?? ''),),
body: Center(
child:iosView(),
),
);
} Widget iosView() { if(defaultTargetPlatform == TargetPlatform.android){ return const AndroidView( viewType: 'plugins.flutter.io/custom_platform_view', ); }else { return Container(); } } } ``` 使用android模擬器執行結果
2. Flutter向android傳值
Dart
AndroidView(
viewType: 'plugins.flutter.io/custom_platform_view',
creationParams: {'text': 'Flutter傳給Android中TextView的引數'},
creationParamsCodec: StandardMessageCodec(),
);
這裡viewType
就是我們註冊的時候使用的識別符號
。creationParams
為建立AndroidView時帶的引數
。creationParamsCodec
:將 creationParams
編碼後再發送給平臺側,它應該與傳遞給建構函式的編解碼器匹配
。
我們在Android專案中TestView
判斷是否傳遞了引數
Dart
init {
args?.also {
textView.text = it["text"] as String
}
}
我們在執行中通過按鈕點選改變AndroidView的內容
js
static const platform = MethodChannel('com.flutter.test.TestView');
我們在flutter頁面定義一個方法通道
```js RaisedButton( child: const Text('傳遞引數給原生View'), onPressed: () { platform.invokeMethod('userInfo', {'name': 'Jack', 'city': "New York"}); },
``` 點選的時候傳參給Android頁面,我們在onMethodCall方法中獲取我們的引數
```js override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { if (call.method == "userInfo") {
val name = call.argument("name") as String?
val city = call.argument("city") as String?
textView.text = "my Name is:,$name,from:$city"
} else {
result.notImplemented()
}
} ```
3. 小結
關於 android中view的傳值邏輯基本和之前的iOS頁面差不多,邏輯上都是通過viewID
來標記唯一性來確定,根據一些key, method
方法等進行互動回撥函式的相互回撥實現通訊
。
- Flutter Module 新增到iOS專案
- Flutter學習-GetX-05 生命週期
- Flutter學習-GetX-04 依賴注入
- ios Xib 使用技巧
- 底層原理-26-Block(上)
- Flutter學習之重新整理元件-pull_to_refresh
- Flutter學習之原生通訊BasicMessageChannel
- flutter學習之嵌入原生View - android
- iOS設計模式之狀態模式
- Flutter學習之嵌入原生iOSView
- flutter學習之狀態管理Provider
- iOS設計模式之代理模式
- iOS設計模式之享元模式
- iOS設計模式之訪問者
- iOS設計模式之迭代器
- iOS設計模式之組合模式
- iOS設計模式之單例模式
- iOS設計模式之生成器模式
- 底層原理-12-dyld動態連結器載入流程
- iOS設計模式之抽象工廠