Flutter异步处理插件future_widget的使用

Flutter异步处理插件future_widget的使用

future_widget 包提供了一种实用且清晰的替代方案来处理 FutureBuilderStreamBuilder。其主要动机在于:

  1. 本地状态缓存future_widget 提供了解决方案来在本地缓存状态,并将本地状态视为首要公民。
  2. 刷新限制FutureWidget 不受 FutureBuilder 中存在的刷新限制影响,后者在不丢弃其状态的情况下无法刷新小部件。通常解决方法是结合 StreamWidgetStreamController 使用,而 FutureWidget 可以在不使用流的情况下实现相同的效果。
  3. 回调简化:与 FutureBuilder(编写代码可能较为繁琐)相比,FutureWidget 提供了 onErroronDataonLoading 回调。

推荐方法

如果您希望直接跳到推荐的方法,请暂时忽略 <a href="#futurewidget">FutureWidget</a> 部分,直接查看 <a href="#futurewidgetwrapper"><strong>FutureWidgetWrapper</strong></a>。直接使用 FutureBuilder 并不是错误,但考虑到 <code>FutureWidgetWrapper</code> 提供的抽象层,它不被推荐。

FutureWidget

FutureWidget 类似于 <a href="https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html"><code>FutureBuilder</code></a><a href="https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html"><code>StreamBuilder</code></a>,因为它需要包裹在一个有状态的小部件中,并且需要通过 <code>setState</code> 调用来刷新(即更改正在监听的未来)。

FutureWidget 的使用

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({Key? key}) : super(key: key);

  [@override](/user/override)
  State<ExampleWidget> createState() => _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget> {
  int a = 9;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return FutureWidgetWrapper<int>(
      futureProvider: () => myFuture4(),
      builder: (context, futureWidgetCtor, isRefreshing, refresh) {
        return Column(
          children: [
            futureWidgetCtor(
              onData: (context, data) {
                return Center(
                  child: Text(
                    'data is: $data${isRefreshing ? '(REFRESHING)' : ''}',
                  ),
                );
              },
              onError: (context, error, stackTrace) {
                return Center(
                  child: Text(
                    'error is: $error${isRefreshing ? '(REFRESHING)' : ''}',
                  ),
                );
              },
              onLoading: (context) {
                return const Center(
                  child: Text('loading'),
                );
              },
            ),
            TextButton(
              onPressed: () {
                refresh(
                  futureProvider: () => myFuture9(),
                );
              },
              child: const Text('刷新小部件 (DATA 9)'),
            ),
            TextButton(
              onPressed: () {
                refresh();
              },
              child: const Text('刷新小部件 (无参数)'),
            ),
            TextButton(
              onPressed: isRefreshing
                  ? null
                  : () {
                      refresh();
                    },
              child: Text(
                isRefreshing
                    ? "按钮在刷新时禁用"
                    : '刷新小部件',
              ),
            ),
            TextButton(
              onPressed: () {
                refresh(
                  disposeState: true,
                );
              },
              child: const Text('重置 (清除状态)'),
            ),
            Text('a is: $a'),
          ],
        );
      },
    );
  }
}

FutureWidgetWrapper

FutureWidgetWrapper 提供了一个高阶抽象层,允许开发者使用单个 <code>refresh</code> 回调执行许多操作,并带有可选参数。

FutureWidgetWrapper 的使用

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({Key? key}) : super(key: key);

  [@override](/user/override)
  State<ExampleWidget> createState() => _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget> {
  int a = 9;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return FutureWidgetWrapper<int>(
      futureProvider: () => myFuture4(),
      builder: (context, futureWidgetCtor, isRefreshing, refresh) {
        return Column(
          children: [
            futureWidgetCtor(
              onData: (context, data) {
                return Center(
                  child: Text(
                    'data is: $data${isRefreshing ? '(REFRESHING)' : ''}',
                  ),
                );
              },
              onError: (context, error, stackTrace) {
                return Center(
                  child: Text(
                    'error is: $error${isRefreshing ? '(REFRESHING)' : ''}',
                  ),
                );
              },
              onLoading: (context) {
                return const Center(
                  child: Text('loading'),
                );
              },
            ),
            TextButton(
              onPressed: () {
                refresh(
                  futureProvider: () => myFuture9(),
                );
              },
              child: const Text('刷新小部件 (DATA 9)'),
            ),
            TextButton(
              onPressed: () {
                refresh();
              },
              child: const Text('刷新小部件 (无参数)'),
            ),
            TextButton(
              onPressed: isRefreshing
                  ? null
                  : () {
                      refresh();
                    },
              child: Text(
                isRefreshing
                    ? "按钮在刷新时禁用"
                    : '刷新小部件',
              ),
            ),
            TextButton(
              onPressed: () {
                refresh(
                  disposeState: true,
                );
              },
              child: const Text('重置 (清除状态)'),
            ),
            Text('a is: $a'),
          ],
        );
      },
    );
  }
}

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

1 回复

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


future_widget 是一个用于简化 Flutter 中异步处理的插件。它允许你在构建 UI 时,轻松地处理异步操作(如网络请求、数据库查询等),并在数据加载完成时自动更新 UI。

安装

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

dependencies:
  flutter:
    sdk: flutter
  future_widget: ^1.0.0  # 请使用最新版本

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

使用示例

future_widget 提供了一个 FutureWidget 组件,它可以接受一个 Future 对象,并在 Future 完成时自动更新 UI。

基本用法

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('FutureWidget Example')),
        body: FutureWidget<String>(
          future: fetchData(),
          loading: () => Center(child: CircularProgressIndicator()),
          error: (error, stackTrace) => Center(child: Text('Error: $error')),
          data: (data) => Center(child: Text('Data: $data')),
        ),
      ),
    );
  }

  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2)); // 模拟网络请求延迟
    return 'Hello, FutureWidget!';
  }
}

参数说明

  • future: 需要处理的 Future 对象。
  • loading: 在 Future 未完成时显示的 Widget。
  • error: 当 Future 发生错误时显示的 Widget。
  • data: 当 Future 成功完成时显示的 Widget,接收 Future 的结果作为参数。

进阶用法

你还可以使用 FutureWidget 的其他特性,例如自定义加载动画、错误处理等。

FutureWidget<String>(
  future: fetchData(),
  loading: () => Center(child: CircularProgressIndicator()),
  error: (error, stackTrace) => Center(child: Text('发生错误: $error')),
  data: (data) => ListView.builder(
    itemCount: data.length,
    itemBuilder: (context, index) => ListTile(
      title: Text(data[index]),
    ),
  ),
)
回到顶部