首页 > 解决方案 > 如何使用颤动中的按钮暂停或恢复异步任务?

问题描述

我正在构建一个 Flutter 应用程序,它需要在一段时间后更改图像。我认为在内部使用带有睡眠方法的while循环可能会解决问题。但它没有,图像只有在循环结束后才会改变。应用程序 UI 也被冻结。

所以,我使用了我无法用按钮控制的异步任务。

期望的输出:图像应每 10 秒更改一次,用户可以暂停或恢复方法执行。

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      body: Center(
        child: Test(
        ),
      ),
    )
  );
  }}
class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  int imgnumber=1;
  int varToCheckButtonPress = 0;
  String BtnTxt = "START";
  void inc(){
    while(imgnumber<10)
      {
        print(imgnumber);
        await Future.delayed(const Duration(seconds: 10));
        setState(() {
          imgnumber++;
        });
      }
  }
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Expanded(flex: 1,
          child: Container(
            child: Image.asset('images/'+imgnumber.toString()+'.png'),
            height: 500,
            width:500,
            color: Colors.green,
          ),
        ),
        FlatButton(
          child: Text(BtnTxt),
          onPressed: (){
            if (varToCheckButtonPress == 0) {
              setState(() {
                inc();
                BtnTxt = 'PAUSE';
                varToCheckButtonPress = 1;
              });
            } else if (varToCheckButtonPress == 1) {
              setState(() {
                BtnTxt = 'RESUME';
                varToCheckButtonPress = 0;
              });
            }
          },
        )
      ],
    );
  }
}

我希望用户使用单个按钮来控制 UI,其 行为类似于 START、PAUSE 和 RESUME我们可以使用普通函数来实现这个功能吗?

标签: flutterdartflutter-layout

解决方案


您应该使用 Bloc 模式来管理您的状态,例如:StreamBuilder、Providers,并制作一个计时器来将新的 imageUrl 推送到 sink 并让 streamBuilder 接收最新的 imageUrl。

至于您的按钮,它所控制的只是计时器。当你点击播放按钮时,new imageUrl 会一直推送到 sink,当你按下 pause 时,只需停止计时器,new image Url 不会将 new imageUrl 推送到 sink,当然,当你点击时重置计时器停止按钮。

这是您可以遵循的非常详细的 Bloc 模式教程:


推荐阅读