本文同步发布于公众号: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();
},
);
}
}
公众号: