本文同步釋出於公眾號:stringwu的網際網路雜談:flutter 的一些概念三
1 Stream 與 Future的關係
Stream
和 Future
都是 Flutter
中常用的非同步程式設計模型,Future
適用於一次性非同步操作,Stream
適用於連續的非同步操作
1.1 Future
Future
一次性的操作,只會返回一個結果;- 可以使用
await
和async
等關鍵字來等待結果 - 可透過
Future.then
方法來處理非同步操作的結果 Future.timeout
來設定超進的時間
1.2 Stream
- Stream是連續的非同步操作,它可以多次返回結果;
- 需要使用StreamController 和 StreamBuilder 來監聽資料流動,並對資料進行處理;
- 可以使用Stream.listen 方法來監聽資料的流動,並進行一個處理
- Stream.timeout 來設定超時的時間
- 使用
StreamController
和StreamSubscription
來實現資料的訂閱和消費
一個簡單的實現資料訂閱和消費邏輯
StreamController<int> _controller = StreamController<int>();
_controller.add(1);
_controller.add(2);
_controller.add(3);
// 訂閱和消費
StreamSubscription<int> _subscription = _controller.stream.listen((int value) {
print(value);
});
2 Widget、State、Context的區別與聯絡
-
Widget
是Flutter
中構建 UI 的基本單位,它描述了一個 UI 元素的外觀和行為。Widget
可以是有狀態的(StatefulWidget
)或無狀態的(Stateless Widget
),可以包含其他Widget
,可以組成 Widget 樹。 -
State
是Widget
的狀態,它描述了Widget
在特定時間點的資料和行為。State
只能存在於有狀態的Widget
中,它可以隨著時間的推移而改變,但不會影響Widget
樹的結構 -
Context
是Flutter
中的上下文物件,它包含了當前Widget
在Widget
樹中的位置和狀態資訊。Context
可以用來獲取當前Theme
、MediaQuery
、Navigator
等資訊,也可以用來建立新的 Widget。
3 PlatformView
PlatformView
可以將原生的檢視嵌入到Flutter
UI中,如嵌入原生地圖,影片播放等。在使用中,需要透過PlatformView Widget
和 PlatformViewFactory
來實現:
PlatformView Widget
用於將原生影片嵌入到應用中;PlatformViewFactory
主要用來建立PlatformView Widget
並將原生檢視與PlatformView Widget
進行關聯;
3.1簡單的使用示例(以Android為例)
首先在原生程式碼中建立一個自定義的PlatformView
// 步驟1 建立一個自定義的PlatformView
class DemoAView :PlatformView {
// 裡面的內容就和在原生中實現自定義View一樣
.....
}
// 步驟2 再建立一個Factory來建立PlatformView
class DemoAViewFactory : PlaformViewFactory {
override fun create(context: Context, id: Int, args: Any?): PlatformView {
// 返回一個PlatfromView
return DemoAView(context)
}
// 步驟2 在Flutter引擎初始化時,註冊一下步驟2建立的factory
// 這個方法是在FlutterFragment中,如果使用的是FlutterActivity,也類似
fun configureFlutterEngine(@NonNull flutterEngine :FlutterEngine ) {
flutterEngine
.getPlatformViewsController()
.getRegistry()
// 注意,這個id 需要是唯一的
.registerViewFactory("demo_a", DemoAViewFactory());
}
然後就可以在Flutter
程式碼中去使用這個PlatformView
(在Flutter
中可以使用PlatformViewLink
來簡化使用,也可以使用AndroidView
和UIKitView
來使用,本文使用PlatformViewLink
來做示例:
class DemoViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return PlatformViewLink(
viewType: "demo_a",
surfaceFactory: (context, controller) {
if (controller is! AndroidViewController) {
return Container(); // 或者返回一個佔位符widget
}
return AndroidViewSurface(
controller: controller,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (params) {
return PlatformViewsService.initAndroidView(
id: params.id,
viewType: "demo_a,
layoutDirection: TextDirection.ltr,
creationParams: {},
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
}
}
公眾號: