第12章 Flutter状态管理与路由¶
学习目标:掌握Flutter状态管理方案(Provider、Riverpod、Bloc)和导航路由系统。
预计学习时间:7-10天 实践时间:3-4天
目录¶
1. 状态管理概述¶
1.1 状态管理方案对比¶
| 方案 | 复杂度 | 适用场景 | 学习曲线 |
|---|---|---|---|
| setState | 低 | 简单页面 | 平缓 |
| Provider | 中 | 中小型应用 | 平缓 |
| Riverpod | 中 | 中大型应用 | 中等 |
| Bloc | 高 | 大型复杂应用 | 陡峭 |
| GetX | 低 | 快速开发 | 平缓 |
1.2 选择建议¶
- 新手:从Provider开始
- 中大型项目:Riverpod或Bloc
- 快速原型:GetX
2. Provider状态管理¶
2.1 基础使用¶
Dart
// 添加依赖
// pubspec.yaml
dependencies:
provider: ^6.1.1
// 定义Model
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void decrement() {
_count--;
notifyListeners();
}
}
// 提供Model
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MyApp(),
),
);
}
// 使用Model
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Consumer<CounterModel>(
builder: (context, counter, child) {
return Text('Count: ${counter.count}');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<CounterModel>().increment();
},
child: Icon(Icons.add),
),
);
}
}
2.2 多Provider管理¶
Dart
// MultiProvider管理多个状态
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserModel()),
ChangeNotifierProvider(create: (_) => CartModel()),
ChangeNotifierProvider(create: (_) => ThemeModel()),
],
child: MyApp(),
),
);
}
3. Riverpod状态管理¶
3.1 基础使用¶
Dart
// 添加依赖
dependencies:
flutter_riverpod: ^2.4.9
// 定义Provider
final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
return CounterNotifier();
});
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() => state++;
void decrement() => state--;
}
// 使用Provider
class CounterPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Scaffold(
body: Center(child: Text('Count: $count')),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).increment(),
child: Icon(Icons.add),
),
);
}
}
4. Bloc状态管理¶
4.1 基础架构¶
Dart
// Event
counter_event.dart
abstract class CounterEvent {}
class CounterIncrementPressed extends CounterEvent {}
class CounterDecrementPressed extends CounterEvent {}
// State
counter_state.dart
class CounterState {
final int count;
CounterState({required this.count});
}
// Bloc
counter_bloc.dart
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(count: 0)) {
on<CounterIncrementPressed>((event, emit) {
emit(CounterState(count: state.count + 1));
});
on<CounterDecrementPressed>((event, emit) {
emit(CounterState(count: state.count - 1));
});
}
}
5. 导航与路由¶
5.1 基础导航¶
Dart
// 页面跳转
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage()),
);
// 返回
Navigator.pop(context);
// 替换页面
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
5.2 命名路由¶
Dart
// 定义路由
MaterialApp(
routes: {
'/': (context) => HomePage(),
'/detail': (context) => DetailPage(),
'/settings': (context) => SettingsPage(),
},
);
// 跳转
Navigator.pushNamed(context, '/detail');
5.3 GoRouter(推荐)¶
Dart
// 添加依赖
dependencies:
go_router: ^12.1.1
// 配置路由
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
),
GoRoute(
path: '/detail/:id',
builder: (context, state) {
final id = state.pathParameters['id'];
return DetailPage(id: id);
},
),
],
);
// 使用
MaterialApp.router(
routerConfig: _router,
);
// 导航
context.go('/detail/123');
context.push('/detail/123');
6. 实践练习¶
练习1:购物车状态管理¶
任务:使用Provider实现购物车功能
要求: - 商品列表 - 添加/删除商品 - 计算总价 - 跨页面状态共享
练习2:新闻应用路由¶
任务:使用GoRouter实现新闻应用导航
要求: - 首页列表 - 详情页(带参数) - 深层链接支持 - 路由守卫
本章小结¶
核心要点¶
- Provider适合中小型应用,学习曲线平缓
- Riverpod是Provider的升级版,更安全易用
- Bloc适合大型复杂应用,逻辑清晰可预测
- GoRouter是Flutter推荐的声明式路由方案
下一步¶
完成本章学习后,请进入第13章:Flutter与原生交互。
本章完成时间:预计7-10天