【Flutter】状态管理:高级状态管理 (Riverpod, BLoC)

打印 上一主题 下一主题

主题 826|帖子 826|积分 2478

当项目变得更加复杂时,简单的状态管理方式(如 setState() 或 Provider)可能不足以有用地处置惩罚应用中状态的变革和业务逻辑的管理。在这种情况下,高级状态管理框架,如 Riverpod 和 BLoC,可以提供更强大的工具,用于处置惩罚复杂的状态流、逻辑分离以及响应式编程。
在本教程中,我们将深入学习 Riverpod 和 BLoC 这两种高级状态管理框架,理解它们的焦点概念,学会如何将业务逻辑与 UI 分离,并利用 Stream 处置惩罚复杂的状态流。
Riverpod 状态管理框架

Riverpod 是由 Provider 的作者开发的一个更加灵活、强大且范例安全的状态管理框架。相比 Provider,Riverpod 提供了更清楚的状态管理方式,同时制止了一些常见的错误和限制。它支持全局和局部的状态管理,适用于大型应用的开发。
安装 Riverpod

首先,在 pubspec.yaml 文件中添加 riverpod 依靠:
  1. dependencies:
  2.   flutter:
  3.     sdk: flutter
  4.   flutter_riverpod: ^2.0.0
复制代码
然后运行 flutter pub get 安装依靠。
Riverpod 焦点概念

在利用 Riverpod 之前,需要相识它的几个焦点概念:


  • Provider:是 Riverpod 的根本状态提供者。它可以创建、管理并共享状态。
  • ConsumerWidget:用于监听 Provider 并响应其状态变革。
  • StateProvider:提供一种简单的方式来管理和监听状态。
  • StateNotifier 和 StateNotifierProvider:用于管理复杂的业务逻辑和状态。
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. // 定义一个 StateProvider 来管理状态
  4. final counterProvider = StateProvider<int>((ref) => 0);
  5. void main() {
  6.   runApp(
  7.     ProviderScope(
  8.       child: MyApp(),
  9.     ),
  10.   );
  11. }
  12. class MyApp extends StatelessWidget {
  13.   @override
  14.   Widget build(BuildContext context) {
  15.     return MaterialApp(
  16.       home: CounterPage(),
  17.     );
  18.   }
  19. }
  20. class CounterPage extends ConsumerWidget {
  21.   @override
  22.   Widget build(BuildContext context, WidgetRef ref) {
  23.     // 通过 ref 读取 counterProvider 的状态
  24.     final counter = ref.watch(counterProvider);
  25.     return Scaffold(
  26.       appBar: AppBar(
  27.         title: Text('Riverpod Counter Example'),
  28.       ),
  29.       body: Center(
  30.         child: Column(
  31.           mainAxisAlignment: MainAxisAlignment.center,
  32.           children: <Widget>[
  33.             Text('You have pushed the button this many times:'),
  34.             Text(
  35.               '$counter',
  36.               style: Theme.of(context).textTheme.headline4,
  37.             ),
  38.           ],
  39.         ),
  40.       ),
  41.       floatingActionButton: FloatingActionButton(
  42.         onPressed: () {
  43.           // 更新状态
  44.           ref.read(counterProvider.notifier).state++;
  45.         },
  46.         tooltip: 'Increment',
  47.         child: Icon(Icons.add),
  48.       ),
  49.     );
  50.   }
  51. }
复制代码
代码详解


  • StateProvider:counterProvider 是一个 StateProvider,它用于管理整型计数器状态。我们界说了一个初始值 0,并通过 ref.watch 监听状态的变革。
  • ProviderScope:这是 Riverpod 的焦点组件,用于提供上下文中可访问的状态。ProviderScope 必须在应用的最顶层。
  • ConsumerWidget:CounterPage 继承自 ConsumerWidget,用于监听状态提供者 counterProvider,并在状态变革时重新构建 UI。
  • 状态更新:ref.read(counterProvider.notifier).state++ 用于更新状态。这里我们通过 read 方法获取 StateProvider 的 notifier,然后修改其状态。
BLoC 状态管理框架

BLoC(Business Logic Component)是一种基于响应式编程的状态管理模式,它通过 Stream 处置惩罚复杂的状态流,实现了业务逻辑和 UI 的完全分离。这种模式适用于大型项目,能够确保代码的可维护性和扩展性。
BLoC 的焦点思想是将变乱流(Event)转换为状态流(State),从而使得业务逻辑独立于界面逻辑。
安装 flutter_bloc

在 pubspec.yaml 文件中添加 flutter_bloc 包依靠:
  1. dependencies:
  2.   flutter:
  3.     sdk: flutter
  4.   flutter_bloc: ^8.0.0
  5.   bloc: ^8.0.0
复制代码
运行 flutter pub get 安装依靠。
BLoC 焦点概念



  • BLoC:用于处置惩罚输入的变乱并输出相应的状态。它封装了业务逻辑和状态转换。
  • Cubit:Cubit 是 BLoC 的简化版本,通常用于处置惩罚简单的状态变革。
  • Stream:BLoC 和 Cubit 都依靠 Stream 来传递状态更新。
  • BlocProvider 和 BlocBuilder:用于提供 BLoC 实例并在 UI 中监听状态变革。
示例:利用 Cubit 实现计数器

  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_bloc/flutter_bloc.dart';
  3. // 定义 Cubit,用于管理计数器状态
  4. class CounterCubit extends Cubit<int> {
  5.   CounterCubit() : super(0);
  6.   void increment() => emit(state + 1);  // 更新状态
  7. }
  8. void main() {
  9.   runApp(MyApp());
  10. }
  11. class MyApp extends StatelessWidget {
  12.   @override
  13.   Widget build(BuildContext context) {
  14.     return MaterialApp(
  15.       home: BlocProvider(
  16.         create: (context) => CounterCubit(),
  17.         child: CounterPage(),
  18.       ),
  19.     );
  20.   }
  21. }
  22. class CounterPage extends StatelessWidget {
  23.   @override
  24.   Widget build(BuildContext context) {
  25.     return Scaffold(
  26.       appBar: AppBar(
  27.         title: Text('BLoC Counter Example'),
  28.       ),
  29.       body: Center(
  30.         child: Column(
  31.           mainAxisAlignment: MainAxisAlignment.center,
  32.           children: <Widget>[
  33.             Text('You have pushed the button this many times:'),
  34.             BlocBuilder<CounterCubit, int>(
  35.               builder: (context, count) {
  36.                 return Text(
  37.                   '$count',
  38.                   style: Theme.of(context).textTheme.headline4,
  39.                 );
  40.               },
  41.             ),
  42.           ],
  43.         ),
  44.       ),
  45.       floatingActionButton: FloatingActionButton(
  46.         onPressed: () {
  47.           // 获取 CounterCubit 实例并调用 increment
  48.           context.read<CounterCubit>().increment();
  49.         },
  50.         tooltip: 'Increment',
  51.         child: Icon(Icons.add),
  52.       ),
  53.     );
  54.   }
  55. }
复制代码
代码详解


  • CounterCubit:Cubit 是 BLoC 的简化版本,用于处置惩罚简单的状态更新。这里我们界说了一个计数器 Cubit,初始状态为 0,并通过 increment() 方法更新状态。
  • BlocProvider:提供 CounterCubit 实例,并使其在子组件中可访问。
  • BlocBuilder:用于监听 Cubit 的状态变革,并根据新的状态更新 UI。
  • 状态更新:通过 context.read<CounterCubit>().increment() 调用 Cubit 的 increment 方法,更新状态。
利用 Stream 处置惩罚复杂状态流

在 BLoC 中,Stream 是焦点工具,用于传递状态更新。我们可以将用户的输入变乱(如点击按钮)作为 Stream 的输入,并将业务逻辑的输出作为状态流输出给 UI。
示例:BLoC 处置惩罚多种变乱

  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_bloc/flutter_bloc.dart';
  3. // 定义事件
  4. abstract class CounterEvent {}
  5. class Increment extends CounterEvent {}
  6. class Decrement extends CounterEvent {}
  7. // 定义 BLoC 类
  8. class CounterBloc extends Bloc<CounterEvent, int> {
  9.   CounterBloc() : super(0);
  10.   @override
  11.   Stream<int> mapEventToState(CounterEvent event) async* {
  12.     if (event is Increment) {
  13.       yield state + 1;
  14.     } else if (event is Decrement) {
  15.       yield state - 1;
  16.     }
  17.   }
  18. }
  19. void main() {
  20.   runApp(MyApp());
  21. }
  22. class MyApp extends StatelessWidget {
  23.   @override
  24.   Widget build(BuildContext context) {
  25.     return MaterialApp(
  26.       home: BlocProvider(
  27.         create: (context) => CounterBloc(),
  28.         child: CounterPage(),
  29.       ),
  30.     );
  31.   }
  32. }
  33. class CounterPage extends StatelessWidget {
  34.   @override
  35.   Widget build(BuildContext context) {
  36.     return Scaffold(
  37.       app
  38. Bar: AppBar(
  39.         title: Text('BLoC Stream Example'),
  40.       ),
  41.       body: Center(
  42.         child: Column(
  43.           mainAxisAlignment: MainAxisAlignment.center,
  44.           children: <Widget>[
  45.             Text('You have pushed the button this many times:'),
  46.             BlocBuilder<CounterBloc, int>(
  47.               builder: (context, count) {
  48.                 return Text(
  49.                   '$count',
  50.                   style: Theme.of(context).textTheme.headline4,
  51.                 );
  52.               },
  53.             ),
  54.           ],
  55.         ),
  56.       ),
  57.       floatingActionButton: Row(
  58.         mainAxisAlignment: MainAxisAlignment.end,
  59.         children: <Widget>[
  60.           FloatingActionButton(
  61.             onPressed: () {
  62.               context.read<CounterBloc>().add(Increment());
  63.             },
  64.             tooltip: 'Increment',
  65.             child: Icon(Icons.add),
  66.           ),
  67.           SizedBox(width: 10),
  68.           FloatingActionButton(
  69.             onPressed: () {
  70.               context.read<CounterBloc>().add(Decrement());
  71.             },
  72.             tooltip: 'Decrement',
  73.             child: Icon(Icons.remove),
  74.           ),
  75.         ],
  76.       ),
  77.     );
  78.   }
  79. }
复制代码
代码解析


  • 变乱范例:CounterEvent 是变乱基类,Increment 和 Decrement 是具体变乱。
  • CounterBloc 类:BLoC 类负责吸收变乱,并利用 mapEventToState 方法将变乱映射为状态更新流。
  • BlocProvider 和 BlocBuilder:与之前的 Cubit 示例类似,BlocProvider 提供 CounterBloc 实例,BlocBuilder 监听状态流并更新 UI。

总结

通过本教程的学习,你已经把握了 Riverpod 和 BLoC 这两种高级状态管理框架。这两种框架都适用于大型项目中的复杂状态管理,能够有用地将业务逻辑与 UI 分离,并通过响应式编程处置惩罚状态流。


  • Riverpod 得当范例安全、灵活的状态管理需求,提供简单易用的 API。
  • BLoC 则非常得当需要严格分离业务逻辑和 UI 的项目,特殊是在需要处置惩罚复杂状态流和多种变乱的情况下。
把握这些工具,将帮助你在现实项目中更加高效地管理复杂状态,构建出高质量的 Flutter 应用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表