Flutter(4)-Widget状态管理
2019-09-26 本文已影响0人
BoxJing
本篇文章介绍一下
Stateful状态的Widget,如何初始化,如何刷新的,在使用的过程中应该如何正确的使用。
来一个看起来和初始化工程很像的代码:
import 'package:flutter/material.dart';
class BoxCounterDemo extends StatefulWidget {
@override
// _BoxCounterDemoState createState() => _BoxCounterDemoState();
// 上面代码和下面的效果一样
State<StatefulWidget> createState() {
return _BoxCounterDemoState();
}
}
class _BoxCounterDemoState extends State<BoxCounterDemo> {
int countNumber = 0;
TextStyle _style = TextStyle(
color: Colors.red,
fontSize: 56
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BoxStateFulDemo'),
),
body: Center(
child: Text('$countNumber',style: _style,),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: (){
countNumber += 1;
setState(() {});//重新刷新! 这一句非常重要
print('count = $countNumber');
},
),
);
}
}
先看一下执行效果,再细细说明:
在前面的文章里已经提到过,只有继承
StatefulWidget的部件,才有刷新的功能,那么StatefulWidget的部件是如何刷新啊,当部件收到setState(){}的调用时Flutter 会重新调用其对应 State 的 build 方法来重新构造 Widget Tree,Flutter 获取到最新的 Widget Tree 后会与当前的 Widget Tree 做对比,绘制不一样的地方,flutter的渲染机制用的是skia,和web的渲染是一样的,具有轻量化和快速的特点。在Flutter中,Widget采用的是React风格,
StatefulWidget类型的部件是将Widget和State写在了两个类中,extends State<T>后面需要指明该State对应的Widget是哪个,之所以要写进2个类里面,是和他们的生命周期有关。Widget相当于时一个暂时的对象,只是为了展示和布局当前状态时用的,只要状态发生了改变,就会失效,而State可以说是永久的,它里面存储了一些必要信息,每次状态改变后,通过比较,只更新和修改差异化的东西。下面来一个带有事件传递,并且含有Stateles的部件代码示例:
class _ChildLessWidget extends StatelessWidget { //stateless
final bool active;
final ValueChanged<bool> onChanged;
_ChildLessWidget({Key key, this.active: false, @required this.onChanged})
: super(key: key);
void _handleTap() {
onChanged(!active);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _handleTap,
child: Container(
alignment: Alignment(0, 0),
child: Text(
'点击更改背景色',
style: new TextStyle(fontSize: 44.0, color: Colors.white),
),
color: active ? Colors.red : Colors.blue,
),
);
}
}
class BoxParentWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _BoxParentWidgetState();
}
}
class _BoxParentWidgetState extends State<BoxParentWidget> {
var _active = false;
_handleDidTap(bool newValue) {
setState(() {
_active = newValue;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BoxStateFulDemo'),
),
body: _ChildLessWidget(
active: _active,
onChanged: _handleDidTap,
),
);
}
}
运行效果是这个样子:
BoxParentWidget是一个Stateful类型的部件,内部含有一个Stateless类型的部件但是我们要想在stateless类型的部件里如何把一个事件传递出来,然后通知Stateful类型的部件需要刷新了,所以我们在_ChildLessWidget的构造函数中将一个Bool值和点击事件进行传递进去,在里面接收后,使用了GestureDetector组件的点击调用私有方法_handleTap,然后触发传参进去的事件onChanged,这样就回调出来进行_handleDidTap的方法调用setState方法的调用。
在后面的开发中会经常用到Widget的状态管理,这里只是简单介绍了一下,相信在后面使用的过程中,我们会掌握越来越多的使用技巧。所有的代码都可以在Github:BoxJ/Flutter-daydayup中下载,本篇代码的文件夹是
boxdemo_004,欢迎一起交流!