在 Flutter 失败时重新运行你的启动逻辑

简介: 本文主要介绍在 Flutter 失败时重新运行你的启动逻辑有时,应用程序必须在启动之前运行异步函数。像加密交易工具这样的东西必须在线,所以他们会在开始时提出登录请求,在线游戏也是如此,或者在我的情况下,一个应用程序在启动时从磁盘(或网络,如果这是第一次)。将它构建到 HomeView 中会很容易,但是一些应用程序,比如我的,根据配置

本文主要介绍在 Flutter 失败时重新运行你的启动逻辑

有时,应用程序必须在启动之前运行异步函数。像加密交易工具这样的东西必须在线,所以他们会在开始时提出登录请求,在线游戏也是如此,或者在我的情况下,一个应用程序在启动时从磁盘(或网络,如果这是第一次)。将它构建到 HomeView 中会很容易,但是一些应用程序,比如我的,根据配置有 4 个不同的启动屏幕,我们不会将它构建到每个视图中。

当启动逻辑失败时,我们希望为用户提供重试的选项。因此,我们需要能够将应用程序再次置于与启动时相同的状态。我们将保持示例简单。当应用程序启动时,我们将运行异步函数。MaterialApp 的主页将是一个 StreamBuilder,它根据流值显示不同的视图。

执行

这就是我们将如何实现功能。在启动 Future 以获取重要数据时将运行。在未来,我们将在 StreamController 经历状态时向其添加值。MaterialApp 的 home 将是一个 StreamBuilder,它监听来自前面提到的控制器的流。根据来自该流的值,我们将显示不同的 UI。更具体地说,以下用户界面:

  • NoData / Busy:带有加载指示器的文本(我们将使用 CircularProgressIndicator,但您也可以使用SpinKit
  • 成功:黄色视图显示主页
  • 错误:带有重试按钮的文本,可重新运行未来以准备好重要数据

我们将从一个基本的应用程序开始

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Container(),
    );
  }
}
复制代码

我们想在应用程序启动时调用 Future,但我希望将 MyApp 保留为无状态小部件,因此我们将创建一个有状态包装器来为我们执行此操作。创建一个名为 stateful_wrapper.dart 的新文件。它是一个有状态的小部件,它接受一个名为 onInit 的函数和一个子小部件。覆盖 initState 函数并在覆盖中调用 onInit。

class StatefulWrapper extends StatefulWidget {
  final Function onInit;
  final Widget child;
  StatefulWrapper({Key key, this.onInit, this.child}) : super(key: key);
  _StatefulWrapperState createState() => _StatefulWrapperState();
}
class _StatefulWrapperState extends State<StatefulWrapper> {
  @override
  void initState() {
    widget.onInit();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}
复制代码

接下来我们将添加我们将使用的状态枚举。你应该把它放在它自己的文件中,我把它放在 main.dart 文件中作为例子

enum StartupState { Busy, Success }
复制代码

现在让我们添加将发出我们的状态的 StreamController 和将完成重要工作并将状态添加到流中的未来。

class MyApp extends StatelessWidget {
  final StreamController<StartupState> _startupStatus = StreamController<StartupState>();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Container(),
    );
  }
   Future getImportantData({bool isError = false}) async {
    _startupStatus.add(StartupState.Busy);
    await Future.delayed(Duration(seconds: 2));
    if (isError) {
      _startupStatus.add(StartupState.Error);
    } else {
      _startupStatus.add(StartupState.Success);
    }
  }
}
复制代码

现在我们可以将它们联系在一起。我们希望在视图初始化时调用未来,因此我们将使用我们的StatefulWrapper并传递一个onInit函数。我们将传递 isError true 以便我们可以遍历所有状态。UI 将是一个 Scaffold,根子StatefulWrapper节点是我们的,而该包装器的子节点将是一个接受startupStatus流的 StreamBuilder 。

@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      body: StatefulWrapper(
          onInit: () => getImportantData(isError: true),
          child: StreamBuilder<StartupState>(
            stream: _startupStatus.stream,
            builder: (context, snapshot) {
            },
          ),
      ),
    ),
  );
}
复制代码

现在我们终于可以添加我们的用户界面了。第一个 UI 位,我们将检查snapShothasData,或者它是否繁忙,我们将显示加载指示器。

if (!snapshot.hasData || snapshot.data == StartupState.Busy) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text('Show your app logo here'),
          CircularProgressIndicator()
        ],
      ),
    );
  }
复制代码

然后我们要检查快照是否为错误类型。如果是,我们将返回错误消息以及可用于重试的 IconButton。

if (snapshot.hasError) {
    return Center(
        child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Text('${snapshot.error} Retry?'),
        IconButton(
          icon: Icon(
            Icons.refresh,
            size: 55,
          ),
          onPressed: () {
            getImportantData();
          },
        )
      ],
    ));
  }
复制代码

在构建器函数的最后,它成功了,我们将显示一个黄色容器。

return Container(color: Colors.yellow);
复制代码

这就是您可以在应用程序启动时设置简单重试的方法。如果您运行该应用程序,您将看到加载指示,完成后您将收到错误消息。点击重试按钮将重新运行 Future,因此您将再次看到加载,然后您将看到成功

相关文章
|
缓存 Java 开发工具
Flutter— 第一次运行Flutter工程时的Bug总结
Flutter— 第一次运行Flutter工程时的Bug总结
 Flutter— 第一次运行Flutter工程时的Bug总结
|
19天前
|
Dart UED
在 Flutter鸿蒙next版本 中使用 if 语句和三元表达式进行视图逻辑判断
在 Flutter 开发中,构建动态和响应式的用户界面是核心任务。本文详细探讨了如何使用 if 语句、三元表达式等方法进行视图逻辑判断,并提供了示例代码。通过这些方法,可以根据不同条件动态渲染组件,提高用户体验。文章还强调了保持代码可读性和合理使用匿名函数的最佳实践。
65 2
|
19天前
|
存储 UED 开发者
Flutter鸿蒙版本灵活使用方法间的回调处理复杂化的逻辑
在 Flutter 开发中,灵活使用函数回调可以提高代码的可重用性、简化异步编程、增强解耦设计和提升用户体验。本文通过一个简单的示例,展示了如何在 Flutter 中实现函数调用和回调的基本使用。示例代码包括主入口、页面组件和回调函数的定义与调用,详细解析了每个部分的功能和作用。通过这种方式,开发者可以在操作完成后执行特定逻辑,使代码更易读和维护。
73 0
|
3月前
|
开发工具 iOS开发
解决Flutter运行报错Could not run build/ios/iphoneos/Runner.app
解决Flutter运行报错Could not run build/ios/iphoneos/Runner.app
141 2
|
3月前
|
iOS开发
解决Flutter运行IOS报错:Podfile is out of date
解决Flutter运行IOS报错:Podfile is out of date
74 1
|
3月前
|
Dart 开发工具 Android开发
Flutter学习:从搭建环境到运行
Flutter学习:从搭建环境到运行
45 0
|
4月前
|
Dart Android开发 iOS开发
flutter 创建项目、运行项目、项目目录
flutter 创建项目、运行项目、项目目录
173 0
|
5月前
|
Dart Serverless Android开发
Flutter 单线程模型保证UI运行流畅
Flutter 单线程模型保证UI运行流畅
73 0
|
6月前
|
机器学习/深度学习 Java Android开发
记录一个Flutter运行的异常FAILURE: Build failed with an exception. What went wrong: A problem occurred config
记录一个Flutter运行的异常FAILURE: Build failed with an exception. What went wrong: A problem occurred config
226 0
|
Dart Android开发
Flutter | vscode运行Flutter疑难杂症
本来今天更新Stable Diffusion最后一个教程的,但是今天在开发中遇到了一个问题。
168 0
Flutter | vscode运行Flutter疑难杂症