一:刷新UI
刷新UI的两种情况:
- 进入页面,网络请求,此时没有数据,等待网络返回结果,返回结果前需要loading
- 页面已经渲染完成,只有少数widget需要修改数据
- 数据共享(InheritedWidget)
1:FutureBuilder
FutureBuilder适用于进入页面,网络请求,此时没有数据,等待网络返回结果,返回结果前需要loading,然后切换到正常的页面
//模拟网络请求,延时两秒返回数据
Future getData() {
return Future.delayed(Duration(seconds: 2),(){return "ok";}).then((value){
print(value);
for (int i= 0;i < 10; i ++){
dataArray.add("woshidi$i");
}
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: FutureBuilder(
future: getData(),
builder: (cxt, feature){
if (feature.connectionState == ConnectionState.done){
return ListView.builder(
itemBuilder: (context, index){
// code...
);
} else {
return Center(child: CircularProgressIndicator(),);
}
},
) ,
);
}
2:使用StatefulWidget搭配setState
使用StatefulWidget搭配setState适用于 页面已经渲染完成,只有少数widget需要修改数据,可以修改指定的widget
InheritedWidget
数据共享(InheritedWidget):它提供了一种数据在widget树中从上到下传递、共享的方式,比如我们在应用的根widget中通过InheritedWidget共享了一个数据,那么我们便可以在任意子widget中来获取该共享的数据!这个特性在一些需要在widget树中共享数据的场景中非常方便!如Flutter SDK中正是通过InheritedWidget来共享应用主题(Theme)和Locale (当前语言环境)信息的。
二:事件
1:Listener
原始指针事件
当指针按下时,Flutter会对应用程序执行命中测试(Hit Test),以确定指针与屏幕接触的位置存在哪些组件(widget), 指针按下事件(以及该指针的后续事件)然后被分发到由命中测试发现的最内部的组件,然后从那里开始,事件会在组件树中向上冒泡,这些事件会从最内部的组件被分发到组件树根的路径上的所有组件,这和Web开发中浏览器的事件冒泡机制相似, 但是Flutter中没有机制取消或停止“冒泡”过程,而浏览器的冒泡是可以停止的。注意,只有通过命中测试的组件才能触发事件。
Listener(
child: Container(width: 200,height: 100,color: Colors.yellow,),
onPointerDown: (event)=> print(event),
onPointerCancel: (event)=> print(event),
onPointerMove: (event)=> print(event),
onPointerUp: (event)=> print(event),
)
//
I/flutter (10683): PointerDownEvent#1a064(position: Offset(166.5, 436.5))
I/flutter (10683): PointerUpEvent#f3c52(position: Offset(166.5, 436.5))
假如我们不想让某个子树响应PointerEvent的话,我们可以使用IgnorePointer
和AbsorbPointer
AbsorbPointer:
本身是可以接收指针事件的(但其子树不行)
IgnorePointer:
本身不会参与,也不可以接受事件
2: GestureDetector
点击、双击、长按、拖动、滑动、缩放
3:GestureRecognizer
GestureDetector内部是使用一个或多个GestureRecognizer来识别各种手势的,而GestureRecognizer的作用就是通过Listener来将原始指针事件转换为语义手势,GestureDetector直接可以接收一个子widget。GestureRecognizer是一个抽象类,一种手势的识别器对应一个GestureRecognizer的子类,Flutter实现了丰富的手势识别器,我们可以直接使用。
问题:竞争与手势冲突
在遇到复杂的冲突场景时,都可以通过Listener直接识别原始指针事件来解决冲突。