- StatefulWidget 拥有 State,对外的类
- State 是 StatefulWidget 的内部逻辑,包括状态管理和UI创建
State 状态发生改变后,调用 setState 会将 StatefulWidget 标记为 需要重建,在下个事件循环中,会将所有白哦纪委需要重建的 widget 一起计算布局并生成渲染树,然后对比新老渲染树,更新需要更细的部分。
setState后发生的事情
- 状态更新
状态更新后,调用 setState - 标记为需要重建
setState后,Flutter框架会将与State关联的Widget标记为需要更新,并在下个事件循环重新绘制这个Widget的UI
3.事件循环
Flutter的事件循环用来处理各种事件,例如用户输入、定时器回调等,当进入事件回调是,Flutter会检查是否有被标记为需要重建的Widget - 绘制UI
重建过程中,Flutter会计算出Widget的布局、尺寸、外观,然后将这些更新合并到一个渲染树 - 更新UI
Flutter对比新旧渲染树,找到改变的部分,并把变化应用到屏幕上
setState性能
- 需要保持StatefulWidget足够小
控制刷新的Widget范围,尽量减少Widget的刷新
总结:不要在页面节点使用 setState
// setState会刷新整体,影响范围大
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
var _value1 = false;
var _value2 = false;
@override
Widget build(BuildContext context) {
this.widget;
return ListView(
children: [
Switch(
value: _value1,
onChanged: (value) {
_value1 = !_value1;
setState(() {});
}),
Switch(
value: _value2,
onChanged: (value) {
_value2 = !_value2;
setState(() {});
}),
],
);
}
}
// setState刷新局部,影响范围小
import 'dart:ffi';
import 'package:best_flutter_ui_templates/fitness_app/bottom_navigation_view/bottom_bar_view.dart';
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
var _value1 = false;
var _value2 = false;
@override
Widget build(BuildContext context) {
this.widget;
return ListView(
children: [
MySwitch(_value1),
MySwitch(_value2),
],
);
}
}
class MySwitch extends StatefulWidget {
final value;
const MySwitch(this.value, {super.key});
@override
State<MySwitch> createState() => _MySwitchState(value);
}
class _MySwitchState extends State<MySwitch> {
_MySwitchState(this.value);
bool value;
@override
Widget build(BuildContext context) {
return Switch(
value: value,
onChanged: (value) {
value = !value;
setState(() {});
});
}
}
- 不要滥用setState
initState和build方法中不要调用setState,initState结束后会触发build构建,无需调用setState
3.setState快速执行
setState结束后会触发 build 构建,不能阻塞它的速度
4.setState() 和 setState(...) 作用相同
setState((){
name= "tom";
})
和下面的效果相同
name= "tom";
setState((){
})