Flutter状态结果管理插件stated_result的使用

Flutter状态结果管理插件stated_result的使用

stated_result 是一个基于 flutter_blocprovider 构建的 Flutter 插件,旨在简化异步操作的状态管理和 UI 呈现。它提供了多种状态结果类型(MultiStateResult),支持从同步到异步结果的转换,并且可以与 BlocValueNotifier 集成。

主要特性

  1. 多状态结果类型

    • ActionResult: 仅包含两种状态 (CompletedFailed)。
    • AsyncActionResult: 包含四种状态 (Pending, Waiting, Completed, Failed)。
    • QueryResult<T>: 包含两种状态 (SucceededFailed),成功时返回值为类型 T
    • AsyncQueryResult<T>: 包含四种状态 (Pending, Waiting, Succeeded, Failed),并支持额外的默认状态 (Default)。
  2. 状态转换

    • 支持将同步结果转换为异步结果。
    • 支持将 Future 转换为 ActionResultQueryResult
  3. UI 构建器

    • 提供 ActionResultBuilderQueryResultBuilder,用于根据状态动态构建 UI。
    • 支持全局默认构建器和局部默认构建器。
  4. 集成支持

    • Bloc 集成,提供 ActionCubitQueryCubit
    • ValueNotifier 集成,提供 ActionNotifierQueryNotifier

使用示例

以下是一个完整的示例,展示如何使用 stated_result 管理异步操作和构建 UI。

1. 添加依赖

pubspec.yaml 文件中添加依赖:

dependencies:
  stated_result: ^x.x.x
2. 定义异步操作

假设我们有一个异步函数 fetchData(),用于模拟 API 调用:

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

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2)); // 模拟网络延迟
  return "Data fetched successfully!";
}
3. 创建 ActionCubit

使用 ActionCubit 来管理异步操作的状态:

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:stated_result/stated_result.dart';

class MyActionCubit extends ActionCubit<String> {
  MyActionCubit() : super(AsyncActionResult.pending());

  void fetchAndSetData() async {
    try {
      final result = await fetchData().asActionResult(); // 将 Future 转换为 AsyncActionResult
      emit(result); // 更新状态
    } catch (e) {
      emit(AsyncActionResult.failed(error: e.toString()));
    }
  }
}
4. 构建 UI

使用 ActionBlocBuilder 根据状态动态呈现 UI:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:stated_result/stated_result.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (context) => MyActionCubit(),
        child: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('stated_result 示例')),
      body: Center(
        child: BlocBuilder<MyActionCubit, AsyncActionResult>(
          builder: (context, state) {
            return ActionResultBuilder(
              result: state,
              pendingBuilder: (_) => Center(child: CircularProgressIndicator()),
              waitingBuilder: (_) => Center(child: Text("Loading...")),
              failedBuilder: (_, error, __) => Center(child: Text("Error: $error")),
              completedBuilder: (_) => Center(child: Text("Success!")),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.read<MyActionCubit>().fetchAndSetData();
        },
        child: Icon(Icons.refresh),
      ),
    );
  }
}
5. 运行效果

运行后,点击浮动按钮触发异步操作,UI 会根据状态变化动态更新:

  • 初始状态:显示加载动画。
  • 异步进行中:显示 “Loading…”。
  • 操作失败:显示错误信息。
  • 操作成功:显示 “Success!”。

全局默认构建器

如果不想每次都手动定义 pendingBuilderwaitingBuilder 等,可以设置全局默认构建器:

void main() {
  DefaultResultBuilder.setGlobalBuilder(
    pendingBuilder: (_) => Center(child: CircularProgressIndicator()),
    waitingBuilder: (_) => Center(child: Text("Waiting...")),
    failedBuilder: (_, error, __) => Center(child: Text("Error: $error")),
    completedBuilder: (_) => Center(child: Text("Success!")),
  );

  runApp(MyApp());
}

这样,所有使用 ActionResultBuilder 的地方都会自动应用这些默认构建器。


处理空列表或空值

当数据可能是空列表或空值时,可以使用 EmptyableContentBuilder

Widget build(BuildContext context) {
  return QueryBlocBuilder<List<String>>(
    bloc: context.read<MyStringListBloc>(),
    builder: (_, list) {
      return EmptyableContentBuilder(
        value: list,
        emptyBuilder: (_) => Center(child: Text("List is empty")),
        builder: (_, list) => ListView.builder(
          itemCount: list.length,
          itemBuilder: (_, index) => ListTile(title: Text(list[index])),
        ),
      );
    },
  );
}
1 回复

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


stated_result 是一个用于 Flutter 的状态管理插件,它提供了一种简单的方式来管理应用程序的状态,并且能够将状态与 UI 进行绑定。stated_result 的核心思想是将状态封装在 Result 对象中,并通过 StateNotifier 来管理这些状态。

安装

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

dependencies:
  flutter:
    sdk: flutter
  stated_result: ^0.1.0 # 请使用最新版本

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

基本用法

1. 创建 StateNotifier

StateNotifierstated_result 的核心类,用于管理状态。你可以通过继承 StateNotifier 来创建自己的状态管理类。

import 'package:stated_result/stated_result.dart';

class CounterNotifier extends StateNotifier<Result<int>> {
  CounterNotifier() : super(const Result.idle());

  void increment() {
    state = const Result.loading();
    try {
      // 模拟异步操作
      Future.delayed(const Duration(seconds: 1), () {
        state = Result.success((state.value ?? 0) + 1);
      });
    } catch (e) {
      state = Result.failure(e);
    }
  }
}

2. 在 UI 中使用 StateNotifier

你可以使用 StateNotifierBuilder 来监听 StateNotifier 的状态变化,并根据不同的状态来更新 UI。

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

class CounterPage extends StatelessWidget {
  final CounterNotifier counterNotifier = CounterNotifier();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter Example')),
      body: Center(
        child: StateNotifierBuilder<Result<int>>(
          stateNotifier: counterNotifier,
          builder: (context, state, _) {
            return state.when(
              idle: () => const Text('Press the button to start'),
              loading: () => const CircularProgressIndicator(),
              success: (value) => Text('Counter: $value'),
              failure: (error) => Text('Error: $error'),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: counterNotifier.increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!