面试题答案
一键面试StatefulWidget 的生命周期
- 创建阶段:
createState
:当StatefulWidget
被插入到 widget 树中时,会调用此方法,它返回一个与该Widget
关联的State
对象。
- Mount 阶段:
initState
:在State
对象插入到 widget 树时被调用,只调用一次,通常用于初始化状态和订阅数据等操作,例如启动定时器、初始化网络请求等。didChangeDependencies
:当State
对象的依赖关系发生变化时被调用,在initState
之后也会调用一次。例如,当父 widget 重建并传递新的数据给子 widget 时,子 widget 的didChangeDependencies
可能会被调用。
- 更新阶段:
build
:当State
对象需要构建或重建其 UI 时调用,每次状态改变或者父 widget 传递新的配置时,都会调用此方法。didUpdateWidget
:当父 widget 重建并传递新的配置给当前StatefulWidget
时调用,会传入旧的 widget 实例,可在此对比新旧配置来决定是否需要更新状态。
- Unmount 阶段:
dispose
:当State
对象从 widget 树中移除时调用,用于清理资源,如取消定时器、关闭流等。
Provider 为 StatefulWidget 提供状态管理
- 状态共享:Provider 使用 InheritedWidget 机制在 widget 树中共享状态,使得子孙 widget 可以轻松获取到该状态而无需通过层层传递。
- 依赖注入:可以将状态对象提供到 widget 树的特定部分,子孙 widget 可以声明依赖该状态,当状态变化时,依赖它的 widget 会自动重建。
示例:在 StatefulWidget 中引入 Provider 管理简单计数器状态
- 添加依赖:在
pubspec.yaml
文件中添加provider
依赖:
dependencies:
provider: ^6.0.3
- 定义计数器状态类:
import 'package:flutter/material.dart';
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
- 使用 Provider 提供状态:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Counter(),
child: MaterialApp(
home: const CounterPage(),
),
);
}
}
class CounterPage extends StatelessWidget {
const CounterPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Counter Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Count: ${context.watch<Counter>().count}',
style: const TextStyle(fontSize: 24),
),
ElevatedButton(
onPressed: () {
context.read<Counter>().increment();
},
child: const Text('Increment'),
)
],
),
),
);
}
}
在上述代码中:
Counter
类继承自ChangeNotifier
,用于管理计数器状态并在状态改变时通知监听器。ChangeNotifierProvider
将Counter
实例提供到 widget 树中。CounterPage
中使用context.watch<Counter>()
获取计数器状态并在 UI 中显示,使用context.read<Counter>().increment()
来更新计数器状态。