深度理解Flutter:有状态Widget与无状态Widget的详细对比
有状态Widget
什么是有状态Widget (StatefulWidget)
官方解释: 如果用户与 widget 交互,widget 会发生变化,那么它就是 有状态的。
有状态的 widget 自身是可动态改变的(基于State)。 例如用户交互而改变 Widget 的 state。
Checkbox、Radio、Slider class - material library - Dart API、 InkWell、Form 和 TextField 都是有状态 widget,它们都是 StatefulWidget 的子类。
Widget
的 状态(state )保存在一个 State
的对象中。 State
和Widget
是分离的,当 Widget
状态变化时,State 对象调用 setState()
来通知框架去重绘 Widget
如何创建一个有状态Widget
实现一个有状态Widget
需要创建两个类:
- 一个
StatefulWidget
的子类,用来定义一个widget
类。 - 一个
State
的子类,包含该widget状态并定义该widget
的 build() 方法。
我们可以通过 VSCode Flutter 命令补全来快速场景一个 有状态组件:
fstful
import 'package:flutter/material.dart';
class FulStatePage extends StatefulWidget {
const FulStatePage({super.key});
_FulStatePageState createState() => _FulStatePageState();
}
class _FulStatePageState extends State<FulStatePage> {
Widget build(BuildContext context) {
return Container(
);
}
}
创建StatefulWidget
子类
上面代码中,我创建了一个 FulStatePage
类 继承了 StatefulWidget
,这时它是一个有状态的Widget
框架在 构建 Widget
时会调用 createState()
创建管理state
,上面代码中,我们创建了 _FulStatePageState
实例.
class FulStatePage extends StatefulWidget {
const FulStatePage({super.key});
_FulStatePageState createState() => _FulStatePageState();
}
上面代码详细解释:
FulStatePage
类继承自StatefulWidget
,表示这是一个具有可变状态的小部件。- 构造函数
const FulStatePage({super.key})
接收一个可选参数key,用于在构建小部件时标识它。 createState()
方法返回一个与FulStatePage关联的状态对象,即_FulStatePageState
。_FulStatePageState
是FulStatePage
对应的状态类,它继承自State类
。- 在
_FulStatePageState
中可以定义和管理该小部件的可变状态
,并实现相关的业务逻辑。 - 通过
重写build()方法
,在其中构建小部件树来描述该小部件的外观和行为。 FulStatePage
类通常会被作为其他小部件的子部件使用,以提供动态交互和数据驱动的功能。
需要注意的是:
FulStatePage
类的构造函数使用了const
关键字,表示该小部件是不可变的,即其属性在构建后不能更改。key
参数用于在小部件树中唯一标识该小部件,以便在进行更新、重建等操作时进行准确定位。createState()
方法必须被重写,用于创建与该小部件关联的状态对象。状态对象State
负责管理和更新小部件的可变状态,并通过setState()
方法通知Flutter框架进行重建。
创建State的子类
_FulStatePageState
类存储可不的信息。
class _FulStatePageState extends State<FulStatePage> {
int num = 0;
void setNum(){
setState(() {
++num
})
}
Widget build(BuildContext context) {
return Container(
);
}
}
上面代码详细解释:
_FulStatePageState
类继承自State<FulStatePage>
,表示它是FulStatePage
小部件的状态类。- 在
build()
方法中,可以构建并返回描述该小部件外观和行为的小部件树。 - 当状态发生变化时,
build()
方法会被调用,以重新构建小部件树来反映新的状态。
需要注意的是:
BuildContext context
参数提供了与当前小部件相关的上下文信息,可以用于获取主题、媒体查询等。- 在
build()
方法中,可以使用各种小部件来构建界面,例如Container、Text、Image等。 - 返回的小部件树描述了该小部件的外观和行为,可以包含其他小部件作为子部件。
- 可以在
build()
方法中使用状态对象的属性来动态生成小部件,实现根据状态变化而改变界面的效果。 - 避免在
build()
方法中进行耗时操作,以保持应用程序的响应性能。 - 如果需要更新状态并触发重建,应使用
setState()
方法。这将通知Flutter框架重新调用build()
方法。
无状态Widget StatelessWidget
在Flutter中,无状态小部件(Stateless Widget)是一种不包含可变状态的小部件。它们是不可变的,意味着一旦构建完成,它们的内容就不能再改变。
无状态小部件通过继承StatelessWidget类来创建,并重写build方法来描述其UI。build方法接收一个BuildContext参数,并返回一个小部件树,用于构建界面。
import 'package:flutter/material.dart';
class CollectPage extends StatelessWidget {
const CollectPage({super.key,});
Widget build(BuildContext context){
return Container();
}
}
什么时候使用无状态Widget
- 当小部件的内容是静态的,不需要根据外部事件或数据进行更新时,可以使用无状态小部件。例如,一个简单的文本展示小部件或一个静态的图标按钮。
- 当小部件的状态由父级管理时,可以使用无状态小部件。父级可以通过传递参数来控制子部件的外观和行为。
- 当小部件不需要响应用户交互时,可以使用无状态小部件。无状态小部件主要用于展示静态内容,而不涉及与用户的交互。
- 当性能要求较高时,无状态小部件比有状态小部件具有更轻量级的性能开销,因为它们不需要维护状态对象。所以,在性能要求较高的场景下,可以考虑使用无状态小部件。
例如一些纯静态展示内容 [文章列表,listview 显示的内容(不需要交互改变weidget), 一些按钮等]
总之,无状态小部件适用于静态内容、由父级管理状态、不需要响应用户交互或对性能要求较高的情况。