Flutter加载指示器插件delayed_consumer_hud的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter加载指示器插件delayed_consumer_hud的使用

Package Version

在本示例中,我们使用了一个带有延迟启动和提供者触发功能的加载指示器。该加载指示器有两个关键特性:能够延迟显示加载指示器,并且可以使用提供者来决定何时显示加载指示器。

这个加载指示器非常适合处理大量快速异步调用的情况,有时这些调用可能会变慢。在这种情况下,你希望有机会在异步调用变慢时显示一个加载指示器。例如,调用Firebase时就可能出现这种情况。

示例

在这个示例中,我们配置了加载指示器,使其在按下加号按钮时显示。我们设置了一个2秒的Future延迟,在延迟结束时将提供者的标志设置为false并隐藏加载指示器。

import 'package:delayed_consumer_hud/delayed_consumer_hud.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Delayed Consumer HUD 示例'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;
  final testViewModel = TestViewModel();

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementSlowCounter() {
    // 这将触发加载指示器
    widget.testViewModel.isBusy = true;

    // 模拟一个长时间操作
    Future<void>.delayed(Duration(seconds: 2)).then((value) {
      setState(() {
        _counter++;
        // 当长时间操作完成时,隐藏加载指示器
        widget.testViewModel.isBusy = false;
      });
    });
  }

  void _incrementFastCounter() {
    // 这将触发加载指示器
    widget.testViewModel.isBusy = true;

    // 模拟一个短时间操作
    Future<void>.delayed(Duration(milliseconds: 100)).then((value) {
      setState(() {
        _counter++;
        // 当短时间操作完成时,隐藏加载指示器
        widget.testViewModel.isBusy = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<TestViewModel>.value(
        value: widget.testViewModel,
        builder: (context, child) {
          return DelayedHud1<TestViewModel>(
            showHud: (value1) {
              return value1.isBusy;
            },
            delayedStart: Duration(milliseconds: 200),
            child: Scaffold(
              appBar: AppBar(
                title: Text(widget.title),
              ),
              body: Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Text(
                        '您已经按下了按钮这么多次:',
                        style: Theme.of(context).textTheme.headline6,
                      ),
                    ),
                    Text(
                      '$_counter',
                      style: Theme.of(context).textTheme.headline4,
                    ),
                    Divider(height: 40),
                    Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Text(
                        '这两个操作都会触发加载指示器的显示。加载指示器有200毫秒的延迟启动。快操作需要100毫秒,慢操作需要2秒。只有慢操作会触发加载指示器的显示。',
                        style: Theme.of(context).textTheme.subtitle1,
                      ),
                    ),
                    ButtonBar(
                      alignment: MainAxisAlignment.center,
                      children: [
                        OutlinedButton(
                          onPressed: _incrementFastCounter,
                          child: Text('快速操作'),
                        ),
                        OutlinedButton(
                          onPressed: _incrementSlowCounter,
                          child: Text('慢速操作'),
                        )
                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        });
  }
}

class TestViewModel extends ChangeNotifier {
  bool _isBusy = false;

  set isBusy(bool value) {
    _isBusy = value;
    notifyListeners();
  }

  bool get isBusy {
    return _isBusy;
  }
}

使用方法

要使用此插件,请在 pubspec.yaml 文件中添加 delayed_consumer_hud 作为依赖项。

显示无延迟和无提供者的HUD

var isBusy = true;

DelayedHud(
  hud: CircularProgressIndicator(),
  child: Text('DelayedHud'),
  showHud: () => _isBusy, // 更新此变量以显示/隐藏HUD
)

显示带1秒延迟和无提供者的HUD

var isBusy = true;

DelayedHud(
  hud: CircularProgressIndicator(),
  child: Text('DelayedHud'),
  delayedStart: Duration(seconds: 1),
  showHud: () => _isBusy, // 更新此变量以显示/隐藏HUD
)

使用ChangeNotificationProvider触发显示HUD

当提供者的值发生变化时,回调 showHud 将被调用,并且提供者将传递给此函数。你可以检查其值以确定是否需要显示HUD。

DelayedHud1<TestViewModel>(
  hud: hud,
  child: Text('DelayedHud1<TestViewModel>'),
  delayedStart: delay,
  showHud: (viewModel) {
    return viewModel.isBusy;
  },
)

使用多个提供者

DelayedHud2<TestViewModel, AnotherViewModel>(
  hud: hud,
  child: Text('Test'),
  delayedStart: delay,
  showHud: (TestViewModel testViewModel, AnotherViewModel anotherViewModel) {
    return testViewModel.isBusy || anotherViewModel.isSaving;
  },
)

自定义

除了使用简单的Widget作为HUD外,你还可以返回一个使用提供者值生成的Widget。

DelayedHud1<TestViewModel>(
  child: Text('DelayedHud1<TestViewModel>'),
  delayedStart: delay,
  showHud: (viewModel) {
    return viewModel.isBusy;
  },
  hudWidget: (viewModel) {
    return Text(viewModel.label);
  }
)

更多关于Flutter加载指示器插件delayed_consumer_hud的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter加载指示器插件delayed_consumer_hud的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用delayed_consumer_hud加载指示器插件的代码案例。delayed_consumer_hud 是一个在延迟操作时显示加载指示器的插件。为了演示如何使用它,我们需要以下几个步骤:

  1. 添加依赖:在pubspec.yaml文件中添加delayed_consumer_hud的依赖。
dependencies:
  flutter:
    sdk: flutter
  delayed_consumer_hud: ^x.y.z  # 请替换为最新版本号
  1. 导入包:在需要使用DelayedConsumerHud的Dart文件中导入包。
import 'package:delayed_consumer_hud/delayed_consumer_hud.dart';
  1. 使用DelayedConsumerHud:在需要显示加载指示器的位置使用DelayedConsumerHud。以下是一个完整的示例,包括一个模拟的异步操作(如从网络获取数据)。
import 'package:flutter/material.dart';
import 'package:delayed_consumer_hud/delayed_consumer_hud.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DelayedConsumerHUD Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 模拟的异步操作,比如从网络获取数据
  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 3));  // 模拟延迟
    return "数据加载完成";
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("DelayedConsumerHUD Demo"),
      ),
      body: DelayedConsumerHud(
        future: fetchData(),  // 传入异步操作
        builder: (context, state) {
          // 根据状态显示不同的内容
          if (state == DelayedConsumerHudState.loading) {
            return Center(child: CircularProgressIndicator());
          } else if (state == DelayedConsumerHudState.success) {
            // 获取到的数据
            final data = fetchData().then((value) => value);
            return Center(child: Text(data.result ?? ""));
          } else if (state == DelayedConsumerHudState.error) {
            return Center(child: Text("加载失败,请重试"));
          } else {
            return Center(child: Text("未知状态"));
          }
        },
        errorWidget: (context) => Center(child: Text("加载失败,请重试")),  // 自定义错误显示
        loadingWidget: (context) => Center(child: CircularProgressIndicator()),  // 自定义加载显示
        successWidget: (context, result) => Center(child: Text(result)),  // 自定义成功显示
        duration: Duration(seconds: 3),  // 延迟显示加载指示器的时间
      ),
    );
  }
}

注意事项

  1. DelayedConsumerHudfuture参数是一个返回Future的异步操作。
  2. builder参数是一个函数,根据加载状态(loading、success、error)返回不同的Widget。
  3. loadingWidgeterrorWidgetsuccessWidget参数允许你自定义不同状态下的Widget显示。
  4. duration参数用于设置延迟显示加载指示器的时间。

以上代码展示了如何在Flutter项目中使用delayed_consumer_hud插件来显示加载指示器。根据具体需求,你可以调整这些代码来适应你的应用场景。

回到顶部