Timer 如何在颤振中从零开始计时?
我试图显示一个计时器(dd HH mm ss格式)来计算每个动作之间的时间(例如按钮动作)。即使应用程序关闭并重建,也需要工作。当前,我加载了一个字符串日期,该日期是我按下按钮时用SharedReference保存的,表示我按下按钮时的时间。我格式化所有时间小数以比较和显示时间差。我觉得它不漂亮,不是我搜索的,我也没有成功地以这种格式显示时钟(dd-HH-mm-ss)。如果有人有一个更简单的例子:) 我也试过这段代码,没关系,当我调用函数时计时器会增加,但我不想要datenow,我只需要从零时间开始Timer 如何在颤振中从零开始计时?,timer,flutter,Timer,Flutter,我试图显示一个计时器(dd HH mm ss格式)来计算每个动作之间的时间(例如按钮动作)。即使应用程序关闭并重建,也需要工作。当前,我加载了一个字符串日期,该日期是我按下按钮时用SharedReference保存的,表示我按下按钮时的时间。我格式化所有时间小数以比较和显示时间差。我觉得它不漂亮,不是我搜索的,我也没有成功地以这种格式显示时钟(dd-HH-mm-ss)。如果有人有一个更简单的例子:) 我也试过这段代码,没关系,当我调用函数时计时器会增加,但我不想要datenow,我只需要从零时间
int _start = 0;
void startTimer() {
_start=0;
var now = new DateTime.now();
const oneSec = const Duration(seconds: 1);
_timer = new Timer.periodic(
oneSec,
(Timer timer) => setState(() {
{
chrono = now.add(new Duration(seconds: _start));
_start = _start + 1;
}
}));
}
编辑:我找到了这个解决方案,但有一些生命周期错误,如果我关闭应用程序,我会松开计时器
Stopwatch stopwatch = new Stopwatch();
void rightButtonPressed() {
setState(() {
if (stopwatch.isRunning) {
stopwatch.reset();
} else {
stopwatch.reset();
stopwatch.start();
}
});
}
@override
Widget build(BuildContext context)
{
...
new Container(height: 80.0,
child: new Center(
child: new TimerText(stopwatch: stopwatch),
)),
...
class TimerText extends StatefulWidget {
TimerText({this.stopwatch});
final Stopwatch stopwatch;
TimerTextState createState() => new TimerTextState(stopwatch: stopwatch);
}
class TimerTextState extends State<TimerText> {
Timer timer;
final Stopwatch stopwatch;
TimerTextState({this.stopwatch}) {
timer = new Timer.periodic(new Duration(milliseconds: 30), callback);
}
void callback(Timer timer) {
if (stopwatch.isRunning) {
setState(() {
});
}
}
@override
Widget build(BuildContext context) {
final TextStyle timerTextStyle = const TextStyle(fontSize: 50.0, fontFamily: "Open Sans");
String formattedTime = TimerTextFormatter.format(stopwatch.elapsedMilliseconds);
return new Text(formattedTime, style: timerTextStyle);
}
}
class TimerTextFormatter {
static String format(int milliseconds) {
int seconds = (milliseconds / 1000).truncate();
int minutes = (seconds / 60).truncate();
int hours = (minutes / 60).truncate();
int days = (hours / 24).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
String hoursStr = (hours % 60).toString().padLeft(2, '0');
String daysStr = (days % 24).toString().padLeft(2, '0');
return "$daysStr:$hoursStr:$minutesStr:$secondsStr";
}
}
秒表秒表=新秒表();
void rightButtonPressed(){
设置状态(){
if(秒表正在运行){
秒表复位();
}否则{
秒表复位();
秒表。开始();
}
});
}
@凌驾
小部件构建(构建上下文)
{
...
新容器(高度:80.0,
孩子:新中心(
子项:新TimerText(秒表:秒表),
)),
...
类TimerText扩展StatefulWidget{
TimerText({this.stopwatch});
最后的秒表;
TimerTextState createState()=>新的TimerTextState(秒表:秒表);
}
类TimerTextState扩展状态{
定时器;
最后的秒表;
TimerTextState({this.stopwatch}){
计时器=新的计时器。周期(新的持续时间(毫秒:30),回调);
}
无效回调(计时器){
if(秒表正在运行){
设置状态(){
});
}
}
@凌驾
小部件构建(构建上下文){
final TextStyle timerTextStyle=常量TextStyle(fontSize:50.0,fontFamily:“开放式SAN”);
String formattedTime=TimerTextFormatter.format(秒表.elapsedmillyses);
返回新文本(formattedTime,样式:timerTextStyle);
}
}
类TimerTextFormatter{
静态字符串格式(整数毫秒){
int seconds=(毫秒/1000).truncate();
int minutes=(秒/60).truncate();
整小时=(分钟/60).truncate();
整数天=(小时/24).truncate();
字符串minutesStr=(分钟数%60).toString().padLeft(2,'0');
字符串secondsStr=(秒数%60).toString().padLeft(2,'0');
字符串hoursStr=(小时数%60).toString().padLeft(2,'0');
字符串daysStr=(天%24).toString().padLeft(2,'0');
返回“$daysStr:$hourstr:$minutesStr:$secondsStr”;
}
}
如果您希望计数器在关闭应用程序后保持不变,则无法将值保存在某个位置(如共享首选项)
使用dateTime.toIso8601String()和dateTime.parse()可以减少保存和加载的麻烦。
要计算通过的时间,可以使用DateTime.now().difference(lastButtonPressed)
应该有一个函数来格式化Duration(),但它尚未实现。我在这里找到了一个:
下面是一个小例子:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutterfly/SharedPrefs.dart';
class TestWidget extends StatefulWidget {
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
DateTime _lastButtonPress;
String _pressDuration;
Timer _ticker;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Time since button pressed"),
Text(_pressDuration),
RaisedButton(
child: Text("Press me"),
onPressed: () {
_lastButtonPress = DateTime.now();
_updateTimer();
sharedPreferences.setString("lastButtonPress",_lastButtonPress.toIso8601String());
},
)
],
),
);
}
@override
void initState() {
super.initState();
final lastPressString = sharedPreferences.getString("lastButtonPress");
_lastButtonPress = lastPressString!=null ? DateTime.parse(lastPressString) : DateTime.now();
_updateTimer();
_ticker = Timer.periodic(Duration(seconds:1),(_)=>_updateTimer());
}
@override
void dispose() {
_ticker.cancel();
super.dispose();
}
void _updateTimer() {
final duration = DateTime.now().difference(_lastButtonPress);
final newDuration = _formatDuration(duration);
setState(() {
_pressDuration = newDuration;
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“包:flutfly/SharedPrefs.dart”;
类TestWidget扩展了StatefulWidget{
@凌驾
_TestWidgetState createState();
}
类_TestWidgetState扩展了状态{
DateTime\u lastButton按;
字符串持续时间;
定时器;
@凌驾
小部件构建(构建上下文){
返回中心(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
文本(“按钮按下后的时间”),
文字(_pressDuration),
升起的按钮(
孩子:文本(“按我”),
已按下:(){
_lastButtonPress=DateTime.now();
_updateTimer();
sharedPreferences.setString(“lastButtonPress”,u lastButtonPress.toIso8601String());
},
)
],
),
);
}
@凌驾
void initState(){
super.initState();
final lastPressString=SharedReferences.getString(“lastButtonPress”);
_lastButtonPress=lastPressString!=null?DateTime.parse(lastPressString):DateTime.now();
_updateTimer();
_ticker=Timer.periodic(持续时间(秒:1),()=>updateTimer());
}
@凌驾
无效处置(){
_ticker.cancel();
super.dispose();
}
void _updateTimer(){
最终持续时间=DateTime.now().difference(_lastbutonpress);
最终newDuration=_formatDuration(duration);
设置状态(){
_按持续时间=新建持续时间;
});
}
字符串\u formatDuration(持续时间){
字符串两位数(整数n){
如果(n>=10)返回“$n”;
返回“0$n”;
}
字符串twoDigitMinutes=twoDigits(持续时间.inMinutes.余数(60));
字符串twoDigitSeconds=twoDigits(duration.unseconds.rements(60));
返回“${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds”;
}
}
为了简单起见,我在全局范围内的main方法中初始化了共享首选项。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutterfly/SharedPrefs.dart';
class TestWidget extends StatefulWidget {
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
DateTime _lastButtonPress;
String _pressDuration;
Timer _ticker;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Time since button pressed"),
Text(_pressDuration),
RaisedButton(
child: Text("Press me"),
onPressed: () {
_lastButtonPress = DateTime.now();
_updateTimer();
sharedPreferences.setString("lastButtonPress",_lastButtonPress.toIso8601String());
},
)
],
),
);
}
@override
void initState() {
super.initState();
final lastPressString = sharedPreferences.getString("lastButtonPress");
_lastButtonPress = lastPressString!=null ? DateTime.parse(lastPressString) : DateTime.now();
_updateTimer();
_ticker = Timer.periodic(Duration(seconds:1),(_)=>_updateTimer());
}
@override
void dispose() {
_ticker.cancel();
super.dispose();
}
void _updateTimer() {
final duration = DateTime.now().difference(_lastButtonPress);
final newDuration = _formatDuration(duration);
setState(() {
_pressDuration = newDuration;
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
}