Flutter状态管理插件stateful_bloc的使用

Flutter状态管理插件stateful_bloc的使用

使用场景

Stateful扩展旨在支持通过Bloc实现的数据加载提交模式。这些模式通常包括以下状态:

  • SubjectInitial
  • SubjectActionInProgress
  • SubjectActionSuccess
  • SubjectActionFailure

它们通常被用作如下方式:

  • SubjectInitial 是构造函数中设置的initialState
  • 当操作被触发时,设置SubjectActionInProgress
  • 执行一些逻辑来获取/发送/转换数据
  • 根据结果设置SubjectActionSuccessSubjectActionFailure

此扩展抽象了状态类型及其转换,只留下由实现者提供的逻辑。

使用比较

以下是一个通用的cubit示例,它向页面提供状态,允许其显示加载指示器和错误消息。

Cubit

纯cubit 带状态的cubit
```dart

class PageCubit extends Cubit<PageState> { PageCubit() : super(PageStateInitial());

void loadPage() { emit(PageStateLoadInProgress()); try { // 数据加载 emit(PageStateLoadSuccess(/* 数据 */)); } catch(e) { emit(PageStateLoadFailure()); } } } |dart class PageCubit extends Cubit<StatefulState<PageData>> with StatefulCubit { PageCubit() : super(StatefulState());

void loadPage() => load(body: () { // 数据加载 return Outcome.finished(PageData(/* 数据 */)); }); }


#### 状态

| 纯cubit状态 | 带状态的状态 |
| --- | --- |
| ```dart
abstract class PageState extends Equatable {
  [@override](/user/override)
  List&lt;Object&gt; get props =&gt; [];
}

class PageStateInitial extends PageState {}

class PageStateLoadInProgress extends PageState {}

class PageStateLoadSuccess extends PageState {
  final String data;

  const LoadSuccess(this.data);

  [@override](/user/override)
  List&lt;Object&gt;? get props =&gt; [data];
}

class PageStateLoadFailure extends PageState {}
``` | ```dart
// 用于 StatefulState&lt;PageData&gt;
class PageData extends Equatable {
  final String data;

  const PageData(this.data);

  [@override](/user/override)
  List&lt;Object&gt;? get props =&gt; [data];
}
``` |

### 优势

使用Stateful扩展的主要优势:

- **简化Cubit/Bloc** - 你不必担心状态,只需关注逻辑和更改的数据。
- **简化状态** - 不再需要为每个组件重复相同的继承树,只需关注提供的数据。
- **统一的状态类型** - 除了标准化本身之外,这使得更容易在多个UI组件之间重用状态依赖的小部件(例如,在`ActionStatus.ongoing`上显示加载指示器或在`ActionStatus.failed`上显示错误消息)。

### 维护者

- [Stanisław Góra](https://github.com/stasgora/)

### 许可证

此库是在[MIT许可证](https://github.com/stasgora/round-spot/blob/master/LICENSE)下授权的。

---

### 完整示例Demo

以下是完整的示例代码:

```dart
import 'package:bloc/bloc.dart';
import 'package:stateful_bloc/stateful_bloc.dart';

class SimpleBlocObserver extends BlocObserver {
  [@override](/user/override)
  void onEvent(Bloc bloc, Object? event) {
    super.onEvent(bloc, event);
    print('onEvent: ${bloc.runtimeType}, event: $event');
  }

  [@override](/user/override)
  void onChange(BlocBase bloc, Change change) {
    super.onChange(bloc, change);
    print('onChange: ${bloc.runtimeType}, change: $change');
  }
}

class TestCubit extends Cubit&lt;StatefulState&lt;int&gt;&gt; with StatefulCubit {
  TestCubit() : super(StatefulState(data: 0));

  void successfullyLoad() =&gt; load(body: () =&gt; Outcome.finished(1));

  void failToSubmit() =&gt; submit(body: () =&gt; Outcome.failed());
}

enum Event { successfullyLoad, failToSubmit }

class TestBloc extends Bloc&lt;Event, StatefulState&lt;int&gt;&gt; with StatefulBloc {
  TestBloc() : super(StatefulState(data: 0));

  [@override](/user/override)
  Stream&lt;StatefulState&lt;int&gt;&gt; mapEventToState(Event event) async* {
    if (event == Event.successfullyLoad) {
      yield* load(body: () =&gt; Outcome.finished(1));
    } else if (event == Event.failToSubmit) {
      yield* submit(body: () =&gt; Outcome.failed());
    }
  }
}

void main() async {
  Bloc.observer = SimpleBlocObserver();

  var cubit = TestCubit();
  cubit.successfullyLoad();
  await Future.delayed(Duration.zero);
  cubit.failToSubmit();
  await Future.delayed(Duration.zero);

  var bloc = TestBloc();
  bloc.add(Event.successfullyLoad);
  bloc.add(Event.failToSubmit);
}

更多关于Flutter状态管理插件stateful_bloc的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter状态管理插件stateful_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


stateful_bloc 是一个 Flutter 状态管理插件,它结合了 BlocStatefulWidget 的优点,提供了一种更简单的方式来管理状态。stateful_bloc 允许你在 StatefulWidget 中使用 Bloc 模式,从而简化状态管理逻辑。

安装 stateful_bloc

首先,你需要在 pubspec.yaml 文件中添加 stateful_bloc 依赖:

dependencies:
  flutter:
    sdk: flutter
  stateful_bloc: ^0.0.1

然后运行 flutter pub get 来安装依赖。

使用 stateful_bloc

1. 创建一个 StatefulBloc

StatefulBloc 是一个继承自 Bloc 的类,它允许你在 StatefulWidget 中管理状态。

import 'package:stateful_bloc/stateful_bloc.dart';

class CounterBloc extends StatefulBloc<int> {
  CounterBloc() : super(0);

  void increment() {
    emit(state + 1);
  }

  void decrement() {
    emit(state - 1);
  }
}

在这个例子中,CounterBloc 管理一个整数状态,并提供了 incrementdecrement 方法来更新状态。

2. 在 StatefulWidget 中使用 StatefulBloc

你可以在 StatefulWidget 中使用 StatefulBloc 来管理状态。

import 'package:flutter/material.dart';
import 'package:stateful_bloc/stateful_bloc.dart';

class CounterPage extends StatefulWidget {
  [@override](/user/override)
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  CounterBloc _bloc;

  [@override](/user/override)
  void initState() {
    super.initState();
    _bloc = CounterBloc();
  }

  [@override](/user/override)
  void dispose() {
    _bloc.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stateful Bloc Counter'),
      ),
      body: Center(
        child: BlocBuilder<CounterBloc, int>(
          bloc: _bloc,
          builder: (context, count) {
            return Text(
              'Count: $count',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => _bloc.increment(),
            child: Icon(Icons.add),
          ),
          SizedBox(height: 10),
          FloatingActionButton(
            onPressed: () => _bloc.decrement(),
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}
回到顶部