Flutter:显示分钟和秒的倒数计时器
Posted
技术标签:
【中文标题】Flutter:显示分钟和秒的倒数计时器【英文标题】:Flutter: Countdown timer that displays minutes and seconds 【发布时间】: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),
)
感谢您提供的任何帮助。
【问题讨论】:
【参考方案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所以问题在于,当您创建 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()
再次启动动画以上是关于Flutter:显示分钟和秒的倒数计时器的主要内容,如果未能解决你的问题,请参考以下文章