在Flutter中,widget分为两类:StatelessWidget(无状态无setstate)和StatefulWidget(有状态有setstate)。
StatelessWidget:
Icon、IconButton, 和Text都是无状态widget, 它们都是 StatelessWidget的子类。StatelessWidget影响的仅仅是自己是无状态的,不回影响他的父Widget和子Widget。多用于根布局、次根布局
class Less extends StatelessWidget {
final String text;
const Less({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Text(text);
}
}
Less包含了一个从外部接受一个不可变的数据源text并将它显示。
无状态的组件的声明周期只有一个:build,它只会在三种情况下被调用:
1、将widget插入树中的时候,也就是第一次构建
2、当widget的父级更改了其配置时,例如,Less的父类改变了text的值
3、当它依赖的InheritedWidget发生变化时
StatefulWidget
Checkbox、FadeImage等都是有状态组件,它们都是StatefulWidget的子类。调用setState通知Flutter框架某个StatefulWidget发生了变化,页面会重新运行build方法,wight可以显示最新的状态
class Full extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _Full();
}
}
class _Full extends State<Full> {
int count = 0;
@override
Widget build(BuildContext context) {
// TODO: implement build
return new GestureDetector(
onTap: onClick,
child: new Text("$count"),
);
}
void onClick() {
setState(() {
count += 1;
});
}
}
Full包含了一个内部持有的int状态,每次点击自增一,使用setState刷新页面显示最新的值。
总结
优先使用StatelessWidget
含有大量子Widget(如根布局、次根布局)最好使用StatelessWidget
StatefulWidget最好用在子节点,同时尽量减少它的子节点。
StatefulWidget,默认我们都是直接调用 setState 来进行配置的刚改或者页面某个数据的变更,但是setState 成本比较高,它会重新绘制当前的整个Widget,所以对于某个父级Widget如果使用ful,当其某个widget数据想要变更时,我们应该考虑单独抽离这个widget-state,或者使用GlobalKey,单独对这个widget进行局部刷新,这样的话就可以避免直接在父widget中setState 造成的性能问题。但需要注意的是 GlobalKey 本身也比较重,也有其他的方式。
网友评论