面试题答案
一键面试区别
- 状态管理
- StatelessWidget:无状态,一旦创建,其属性(
final
修饰)就不可变。它的状态在整个生命周期内不会改变。例如,一个简单的文本标签,其文本内容在创建后不会动态变化。 - StatefulWidget:有状态,其状态可以在用户交互或其他事件触发时改变。状态保存在与之关联的
State
对象中,State
对象可以通过setState
方法来通知Flutter框架状态已改变,从而触发UI更新。
- StatelessWidget:无状态,一旦创建,其属性(
- 生命周期
- StatelessWidget:只有一个
build
方法,每次需要构建UI时就调用该方法。 - StatefulWidget:关联的
State
对象有多个生命周期方法,如initState
(在State对象插入到树中时调用,用于初始化状态)、didUpdateWidget
(当StatefulWidget的配置发生变化时调用)、dispose
(当State对象从树中移除时调用,用于清理资源)等,同时也有build
方法用于构建UI。
- StatelessWidget:只有一个
- 性能
- StatelessWidget:由于状态不可变,渲染性能相对较高,因为不需要处理状态变化带来的额外开销。
- StatefulWidget:由于状态可变,每次状态变化可能会触发UI重新构建,在复杂场景下可能会影响性能,需要合理使用
setState
来优化,避免不必要的UI更新。
应用场景
- 优先选择StatelessWidget的场景
- 静态展示:如展示固定文本、图片的组件。例如一个显示应用名称的标题栏,标题内容固定不变,使用
StatelessWidget
即可。
class AppTitle extends StatelessWidget { @override Widget build(BuildContext context) { return Text('My App Title'); } }
- 纯粹的展示组件,不依赖任何可变状态:像一个简单的分割线组件,其外观不随任何状态变化。
class DividerLine extends StatelessWidget { @override Widget build(BuildContext context) { return Divider(); } }
- 静态展示:如展示固定文本、图片的组件。例如一个显示应用名称的标题栏,标题内容固定不变,使用
- 优先选择StatefulWidget的场景
- 用户交互组件:如按钮点击后需要改变颜色或文本内容。例如一个切换开关,开关状态会在用户点击时改变。
class ToggleSwitch extends StatefulWidget { @override _ToggleSwitchState createState() => _ToggleSwitchState(); } class _ToggleSwitchState extends State<ToggleSwitch> { bool isOn = false; @override Widget build(BuildContext context) { return Switch( value: isOn, onChanged: (value) { setState(() { isOn = value; }); }, ); } }
- 数据动态更新的组件:如一个实时显示时间的时钟组件,时间不断变化,需要使用
StatefulWidget
来更新UI展示。
class RealTimeClock extends StatefulWidget { @override _RealTimeClockState createState() => _RealTimeClockState(); } class _RealTimeClockState extends State<RealTimeClock> { DateTime currentTime = DateTime.now(); @override void initState() { super.initState(); Timer.periodic(Duration(seconds: 1), (timer) { setState(() { currentTime = DateTime.now(); }); }); } @override Widget build(BuildContext context) { return Text(currentTime.toString()); } }