【问题标题】:Flutter: Countdown timer that displays minutes and secondsFlutter:显示分钟和秒的倒数计时器
【发布时间】:2020-04-19 15:58:05
【问题描述】:

我创建了一个倒数计时器,它将从用户输入的持续时间开始倒计时,以分钟为单位。

倒数计时器在技术上有效,但仅显示分钟数。秒数始终保持在 :00。

如何让秒数也显示为倒计时的一部分?

这里是相关代码,摘自一个较长的文件。如果需要,我可以添加更多内容。

各段代码分解如下:

首先,我有一个实际显示计时器文本并允许对其进行样式设置的类:

class Countdown extends AnimatedWidget {
  Countdown({ Key key, this.animation }) : super(key: key, listenable: animation);
  Animation<int> animation;

  @override

  build(BuildContext context){

    Duration clockTimer = Duration(seconds: animation.value*60);

    String timerText = '${clockTimer.inMinutes.remainder(60).toString()}:${(clockTimer.inSeconds.remainder(60) % 60).toString().padLeft(2, '0')}';

    return Text(
      "$timerText",
      style: TextStyle(         
        fontSize: 110,
        color: Theme.of(context).primaryColor,
      ),
    );

  }
}

我有一个动画控制器如下:

AnimationController _controller;

  @override

  void dispose(){
    _controller.dispose();
    super.dispose();
  }

  void initState() {
    super.initState();
    @override

      _controller = AnimationController(
          vsync: this,
        duration: Duration(minutes: gameData.levelClock)  // gameData.levelClock is a user entered number elsewhere in the applciation
      );


  }

最后是调用 Countdown 小部件的代码部分:

Countdown(
     animation: StepTween(
     begin: gameData.levelClock,   // THIS IS A USER ENTERED NUMBER 
     end: 0,
   ).animate(_controller),
)

感谢您提供的任何帮助。

【问题讨论】:

    标签: flutter dart flutter-animation


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    您的 AnimationController 持续时间需要使用秒
    代码sn-p

    _controller = AnimationController(
            vsync: this,
            duration: Duration(
                seconds:
                    levelClock) // gameData.levelClock is a user entered number elsewhere in the applciation
            );
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      int _counter = 0;
      AnimationController _controller;
      int levelClock = 180;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      void initState() {
        super.initState();
    
        _controller = AnimationController(
            vsync: this,
            duration: Duration(
                seconds:
                    levelClock) // gameData.levelClock is a user entered number elsewhere in the applciation
            );
    
        _controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Countdown(
                  animation: StepTween(
                    begin: levelClock, // THIS IS A USER ENTERED NUMBER
                    end: 0,
                  ).animate(_controller),
                ),
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    class Countdown extends AnimatedWidget {
      Countdown({Key key, this.animation}) : super(key: key, listenable: animation);
      Animation<int> animation;
    
      @override
      build(BuildContext context) {
        Duration clockTimer = Duration(seconds: animation.value);
    
        String timerText =
            '${clockTimer.inMinutes.remainder(60).toString()}:${clockTimer.inSeconds.remainder(60).toString().padLeft(2, '0')}';
    
        print('animation.value  ${animation.value} ');
        print('inMinutes ${clockTimer.inMinutes.toString()}');
        print('inSeconds ${clockTimer.inSeconds.toString()}');
        print('inSeconds.remainder ${clockTimer.inSeconds.remainder(60).toString()}');
    
        return Text(
          "$timerText",
          style: TextStyle(
            fontSize: 110,
            color: Theme.of(context).primaryColor,
          ),
        );
      }
    }
    

    【讨论】:

    • 如何使用文本大小
    • "vsync: this" 显示错误,无法编译。
    • @Kamlesh,我再次完整测试。它工作正常。你忘了使用 TickerProviderStateMixin => State 和 TickerProviderStateMixin
    【解决方案2】:

    所以问题在于,当您创建 CountDown 小部件时,您将 begin 设置为一个 double 值,这是您的计时器的分钟值(对于此示例,该值是 5)。随着动画的继续,它将从begin 倒计时到end(在这种情况下为0)。超过 5 分钟,它会从 5 变为 0。

    然后您使用该值并将其转换为秒,但由于动画的值介于 0 和 5 之间,它总是会给您 5:00、4:00、3:00、2:00、1:00 或0:00。

    解决方案是将您的代码更改为

    Countdown(
         animation: StepTween(
         begin: gameData.levelClock * 60, // convert to seconds here
         end: 0,
       ).animate(_controller),
    )
    

    然后在倒计时小部件中将Duration 更改为

    Duration clockTimer = Duration(seconds: animation.value);
    

    您可以在 DartPad here 上找到一个工作示例

    【讨论】:

    • 如果想通过单击按钮重新开始倒计时,有什么办法吗?
    • @ali 是的,只需调用_controller.reset() 将动画控制器重置为其初始值,然后调用_controller.forward() 再次启动动画
    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多