Flutter异步钩子工具插件hooks_async_utils的使用

Flutter异步钩子工具插件hooks_async_utils的使用

hooks_async_utils 是一个用于处理异步操作的 Flutter 插件。通过该插件,你可以轻松地创建任务钩子来防止重复点击,并在异步操作期间更新进度。

创建任务钩子

首先,你需要创建一个任务钩子。使用 useAsyncTask() 方法可以实现这一点:

final incrementTask = useAsyncTask();

使用任务钩子

接下来,你可以将这个任务钩子绑定到按钮的点击事件上。这样可以确保在异步操作执行时,按钮不会被重复点击。以下是一个完整的示例代码:

floatingActionButton: FloatingActionButton(
  onPressed: incrementTask.asyncTaskCallback((progress) async {
    progress.progressLabel = 'Doing something exciting..';
    await Future.delayed(const Duration(seconds: 2));
    progress.progressLabel = 'Almost done.';
    await Future.delayed(const Duration(seconds: 1));
    count.value = count.value + 1;
  }),
  child: incrementTask.task == null
      ? const Icon(Icons.add)
      : const CircularProgressIndicator(),
),

在这个示例中,当按钮被点击时,会触发一个异步操作。在操作执行过程中,按钮会显示一个加载指示器,防止重复点击。一旦操作完成,按钮会恢复为原来的图标状态。

完整示例代码

以下是完整的示例代码,展示了如何使用 hooks_async_utils 插件:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_async_utils/hooks_async_utils.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends HookWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final incrementTask = useAsyncTask();
    final count = useState(0);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Example App'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: incrementTask.asyncTaskCallback((progress) async {
          progress.progressLabel = 'Doing something exciting..';
          await Future.delayed(const Duration(seconds: 2));
          progress.progressLabel = 'Almost done.';
          await Future.delayed(const Duration(seconds: 1));
          count.value = count.value + 1;
        }),
        child: incrementTask.task == null
            ? const Icon(Icons.add)
            : const CircularProgressIndicator(),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ...?(() {
              final task = incrementTask.task;
              if (task == null) {
                return null;
              }
              return <Widget>[
                Text(task.progressLabel ?? 'Doing work'),
              ];
            })(),
            Text(count.value.toString()),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


hooks_async_utils 是一个 Flutter 插件,它提供了一些用于简化异步操作的钩子(Hooks)。这个插件是基于 flutter_hooks 的扩展,允许你在函数组件中使用钩子来管理异步状态、数据加载、以及其他异步操作。

以下是如何使用 hooks_async_utils 的一些常见用例和示例。

1. 安装依赖

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

dependencies:
  flutter:
    sdk: flutter
  flutter_hooks: ^0.18.0
  hooks_async_utils: ^0.1.0

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

2. 使用 useAsyncData 钩子

useAsyncData 是一个常用的钩子,用于处理异步数据加载。它可以帮助你管理加载状态、错误处理和数据的刷新。

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_async_utils/hooks_async_utils.dart';

class MyWidget extends HookWidget {
  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2));
    return 'Hello, Async Data!';
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final asyncData = useAsyncData(
      fetchData,
      key: 'my_data', // 可选的键,用于标识这个异步操作
    );

    return Scaffold(
      appBar: AppBar(
        title: Text('Async Data Example'),
      ),
      body: Center(
        child: asyncData.when(
          loading: () => CircularProgressIndicator(),
          error: (error, stackTrace) => Text('Error: $error'),
          success: (data) => Text('Data: $data'),
        ),
      ),
    );
  }
}

3. 使用 useAsyncCallback 钩子

useAsyncCallback 可以用于处理带有异步操作的按钮点击事件。它会自动处理加载状态和错误。

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_async_utils/hooks_async_utils.dart';

class MyWidget extends HookWidget {
  Future<void> performAsyncAction() async {
    await Future.delayed(Duration(seconds: 2));
    print('Async Action Completed!');
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final asyncCallback = useAsyncCallback(performAsyncAction);

    return Scaffold(
      appBar: AppBar(
        title: Text('Async Callback Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: asyncCallback.execute,
          child: asyncCallback.when(
            loading: () => CircularProgressIndicator(),
            error: (error) => Text('Error: $error'),
            idle: () => Text('Perform Action'),
          ),
        ),
      ),
    );
  }
}

4. 使用 useStream 钩子

useStream 钩子可以用于监听一个 Stream,并在数据更新时自动重建组件。

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_async_utils/hooks_async_utils.dart';

class MyWidget extends HookWidget {
  Stream<int> counterStream() async* {
    int count = 0;
    while (true) {
      await Future.delayed(Duration(seconds: 1));
      yield count++;
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final streamData = useStream(counterStream());

    return Scaffold(
      appBar: AppBar(
        title: Text('Stream Example'),
      ),
      body: Center(
        child: streamData.when(
          loading: () => CircularProgressIndicator(),
          error: (error) => Text('Error: $error'),
          success: (data) => Text('Count: $data'),
        ),
      ),
    );
  }
}

5. 使用 useMemoizeduseEffect 钩子

useMemoized 可以用于缓存复杂的计算结果,而 useEffect 可以用于处理副作用。

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

class MyWidget extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final expensiveValue = useMemoized(() {
      // 模拟一个耗时的计算
      return _calculateExpensiveValue();
    });

    useEffect(() {
      // 模拟一个副作用
      print('Expensive Value: $expensiveValue');
      return () {
        // 清除副作用
        print('Cleaning up...');
      };
    }, [expensiveValue]);

    return Scaffold(
      appBar: AppBar(
        title: Text('Memoized and Effect Example'),
      ),
      body: Center(
        child: Text('Value: $expensiveValue'),
      ),
    );
  }

  int _calculateExpensiveValue() {
    // 模拟一个耗时的计算
    return DateTime.now().millisecondsSinceEpoch % 100;
  }
}
回到顶部