秒表和计时器,颤动问题
stopwatch and timer, problems with flutter
我是 dart 和 flutter 的新手,目前我正在学习,所以请不要因为这个(也许)简单的问题来评判我。
我正在尝试构建一个计时器,但我所有的代码都是从秒表开始的,所以我想这是第一个问题。
简而言之,我正在尝试创建一个 3 分钟的计时器,我可以随时停止和开始(它应该是一个裁判工具)但我的起始字符串是 '03:00' 我可以看到,所以没关系,但我找不到任何关于时间如何 运行 从 03:00 分钟到 00:00 的答案。
另外,正如您在我的代码中看到的那样,我创建了一个按钮来重置时间,但它总是回到 00:00 而不是 03:00。
谁能帮忙?我肯定错过了什么。
import 'dart:async';
import 'package:flutter/material.dart';
class NewStopWatch extends StatefulWidget {
@override
_NewStopWatchState createState() => _NewStopWatchState();
}
class _NewStopWatchState extends State<NewStopWatch> {
Stopwatch watch = Stopwatch();
Timer timer;
bool startStop = true;
IconData btnPlayStatus = Icons.play_arrow;
String elapsedTime = '03:00';
updateTime(Timer timer) {
if (watch.isRunning) {
setState(() {
elapsedTime = transformMilliSeconds(watch.elapsedMilliseconds);
});
}
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(elapsedTime, style: TextStyle(fontSize: 60.0)),
SizedBox(height: 20.0),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn1",
backgroundColor: Colors.blueGrey,
onPressed: () => startOrStop(),
child: Icon(btnPlayStatus)),
),
SizedBox(width: 20.0),
Container(
width: 30,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn2",
backgroundColor: Colors.blueGrey,
onPressed: () => resetWatch(), //resetWatch,
child: Icon(Icons.subdirectory_arrow_left)),
),
],
)
],
),
);
}
resetWatch() {
setState(() {
watch.reset();
setTime();
});
}
startOrStop() {
if(startStop) {
setState(() {
btnPlayStatus = Icons.pause;
});
startWatch();
} else {
setState(() {
btnPlayStatus = Icons.play_arrow;
});
stopWatch();
}
}
startWatch() {
setState(() {
startStop = false;
watch.start();
timer = Timer.periodic(Duration(milliseconds: 100), updateTime);
});
}
stopWatch() {
setState(() {
startStop = true;
watch.stop();
setTime();
});
}
setTime() {
var timeSoFar = watch.elapsedMilliseconds;
setState(() {
elapsedTime = transformMilliSeconds(timeSoFar);
});
}
transformMilliSeconds(int milliseconds) {
int hundreds = (milliseconds / 10).truncate();
int seconds = (hundreds / 100).truncate();
int minutes = (seconds / 60).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
return "$minutesStr:$secondsStr";
}
}
首先你要考虑你是否总是想从3分钟开始;如果是这样,请创建一个静态字段,如下所示:
static duration = new Duration(minutes:3);
编辑:我重构了您的代码并使其正常工作。
updateTimer(Timer t) {
if (watch.isRunning) {
setState(() {
Duration newDuration = _NewStopWatchState.duration -
new Duration(milliseconds: watch.elapsedMilliseconds);
elapsedTime = durationToMinutesAndSeconds(newDuration);
});
}
}
这是updateTimer函数。
接下来,您没有更新 stopWatch() 函数来处理新的更改,所以我为您更改了它。
stopWatch() {
setState(() {
startStop = true;
watch.stop();
Duration newDuration = _NewStopWatchState.duration -
new Duration(milliseconds: watch.elapsedMilliseconds);
elapsedTime = durationToMinutesAndSeconds(newDuration);
});
}
我还更新了 resetWatch() 函数
resetWatch() {
setState(() {
watch.reset();
elapsedTime = durationToMinutesAndSeconds(_NewStopWatchState.duration);
});
}
我还创建了一个实用函数来将持续时间转换为分钟和秒。
String durationToMinutesAndSeconds(Duration d) {
return "${d.inMinutes.toString().padLeft(2, '0')}" +
":${d.inSeconds.remainder(60).toString().padLeft(2, '0')}";
}
我已经在我的机器上试过了,代码可以正常工作,希望这次在你这边也能正常工作。
修改后的代码:
import 'dart:async';
import 'package:flutter/material.dart';
class NewStopWatch extends StatefulWidget {
@override
_NewStopWatchState createState() => _NewStopWatchState();
}
class _NewStopWatchState extends State<NewStopWatch> {
Stopwatch watch = Stopwatch();
Timer timer;
bool startStop = true;
static Duration duration = Duration(minutes:3);
IconData btnPlayStatus = Icons.play_arrow;
String elapsedTime = '';
updateTimer() {
if (watch.isRunning) {
setState(() {
elapsedTime = transformMilliSeconds(_NewStopWatchState.duration.inMilliseconds - watch.elapsedMilliseconds);
});
}
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(elapsedTime),
SizedBox(height: 20.0),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn1",
backgroundColor: Colors.blueGrey,
onPressed: () => startOrStop(),
child: Icon(btnPlayStatus)),
),
SizedBox(width: 20.0),
Container(
width: 30,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn2",
backgroundColor: Colors.blueGrey,
onPressed: () => resetWatch(), //resetWatch,
child: Icon(Icons.subdirectory_arrow_left)),
),
],
),
],
),
);
}
resetWatch() {
setState(() {
watch.reset();
setTime();
elapsedTime="${_NewStopWatchState.duration
.inMinutes}:${_NewStopWatchState.duration.inSeconds.remainder(60)}";
});
}
startOrStop() {
if(startStop) {
setState(() {
btnPlayStatus = Icons.pause;
});
startWatch();
} else {
setState(() {
btnPlayStatus = Icons.play_arrow;
});
stopWatch();
}
}
startWatch() {
setState(() {
startStop = false;
watch.start();
timer = Timer.periodic(Duration(milliseconds: 100), updateTimer());
});
}
stopWatch() {
setState(() {
startStop = true;
watch.stop();
setTime();
});
}
setTime() {
var timeSoFar = watch.elapsedMilliseconds;
setState(() {
elapsedTime = transformMilliSeconds(timeSoFar);
});
}
transformMilliSeconds(int milliseconds) {
int hundreds = (milliseconds / 10).truncate();
int seconds = (hundreds / 100).truncate();
int minutes = (seconds / 60).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
return "$minutesStr:$secondsStr";
}
}
如果你想要一个带计时器的秒表,你可以使用我的简单 github 项目。
我希望这会对某些人有所帮助。谢谢。
我是 dart 和 flutter 的新手,目前我正在学习,所以请不要因为这个(也许)简单的问题来评判我。 我正在尝试构建一个计时器,但我所有的代码都是从秒表开始的,所以我想这是第一个问题。 简而言之,我正在尝试创建一个 3 分钟的计时器,我可以随时停止和开始(它应该是一个裁判工具)但我的起始字符串是 '03:00' 我可以看到,所以没关系,但我找不到任何关于时间如何 运行 从 03:00 分钟到 00:00 的答案。 另外,正如您在我的代码中看到的那样,我创建了一个按钮来重置时间,但它总是回到 00:00 而不是 03:00。 谁能帮忙?我肯定错过了什么。
import 'dart:async';
import 'package:flutter/material.dart';
class NewStopWatch extends StatefulWidget {
@override
_NewStopWatchState createState() => _NewStopWatchState();
}
class _NewStopWatchState extends State<NewStopWatch> {
Stopwatch watch = Stopwatch();
Timer timer;
bool startStop = true;
IconData btnPlayStatus = Icons.play_arrow;
String elapsedTime = '03:00';
updateTime(Timer timer) {
if (watch.isRunning) {
setState(() {
elapsedTime = transformMilliSeconds(watch.elapsedMilliseconds);
});
}
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(elapsedTime, style: TextStyle(fontSize: 60.0)),
SizedBox(height: 20.0),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn1",
backgroundColor: Colors.blueGrey,
onPressed: () => startOrStop(),
child: Icon(btnPlayStatus)),
),
SizedBox(width: 20.0),
Container(
width: 30,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn2",
backgroundColor: Colors.blueGrey,
onPressed: () => resetWatch(), //resetWatch,
child: Icon(Icons.subdirectory_arrow_left)),
),
],
)
],
),
);
}
resetWatch() {
setState(() {
watch.reset();
setTime();
});
}
startOrStop() {
if(startStop) {
setState(() {
btnPlayStatus = Icons.pause;
});
startWatch();
} else {
setState(() {
btnPlayStatus = Icons.play_arrow;
});
stopWatch();
}
}
startWatch() {
setState(() {
startStop = false;
watch.start();
timer = Timer.periodic(Duration(milliseconds: 100), updateTime);
});
}
stopWatch() {
setState(() {
startStop = true;
watch.stop();
setTime();
});
}
setTime() {
var timeSoFar = watch.elapsedMilliseconds;
setState(() {
elapsedTime = transformMilliSeconds(timeSoFar);
});
}
transformMilliSeconds(int milliseconds) {
int hundreds = (milliseconds / 10).truncate();
int seconds = (hundreds / 100).truncate();
int minutes = (seconds / 60).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
return "$minutesStr:$secondsStr";
}
}
首先你要考虑你是否总是想从3分钟开始;如果是这样,请创建一个静态字段,如下所示:
static duration = new Duration(minutes:3);
编辑:我重构了您的代码并使其正常工作。
updateTimer(Timer t) {
if (watch.isRunning) {
setState(() {
Duration newDuration = _NewStopWatchState.duration -
new Duration(milliseconds: watch.elapsedMilliseconds);
elapsedTime = durationToMinutesAndSeconds(newDuration);
});
}
}
这是updateTimer函数。 接下来,您没有更新 stopWatch() 函数来处理新的更改,所以我为您更改了它。
stopWatch() {
setState(() {
startStop = true;
watch.stop();
Duration newDuration = _NewStopWatchState.duration -
new Duration(milliseconds: watch.elapsedMilliseconds);
elapsedTime = durationToMinutesAndSeconds(newDuration);
});
}
我还更新了 resetWatch() 函数
resetWatch() {
setState(() {
watch.reset();
elapsedTime = durationToMinutesAndSeconds(_NewStopWatchState.duration);
});
}
我还创建了一个实用函数来将持续时间转换为分钟和秒。
String durationToMinutesAndSeconds(Duration d) {
return "${d.inMinutes.toString().padLeft(2, '0')}" +
":${d.inSeconds.remainder(60).toString().padLeft(2, '0')}";
}
我已经在我的机器上试过了,代码可以正常工作,希望这次在你这边也能正常工作。
修改后的代码:
import 'dart:async';
import 'package:flutter/material.dart';
class NewStopWatch extends StatefulWidget {
@override
_NewStopWatchState createState() => _NewStopWatchState();
}
class _NewStopWatchState extends State<NewStopWatch> {
Stopwatch watch = Stopwatch();
Timer timer;
bool startStop = true;
static Duration duration = Duration(minutes:3);
IconData btnPlayStatus = Icons.play_arrow;
String elapsedTime = '';
updateTimer() {
if (watch.isRunning) {
setState(() {
elapsedTime = transformMilliSeconds(_NewStopWatchState.duration.inMilliseconds - watch.elapsedMilliseconds);
});
}
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(elapsedTime),
SizedBox(height: 20.0),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn1",
backgroundColor: Colors.blueGrey,
onPressed: () => startOrStop(),
child: Icon(btnPlayStatus)),
),
SizedBox(width: 20.0),
Container(
width: 30,
height: 50,
child: FloatingActionButton(
shape: ContinuousRectangleBorder(),
heroTag: "btn2",
backgroundColor: Colors.blueGrey,
onPressed: () => resetWatch(), //resetWatch,
child: Icon(Icons.subdirectory_arrow_left)),
),
],
),
],
),
);
}
resetWatch() {
setState(() {
watch.reset();
setTime();
elapsedTime="${_NewStopWatchState.duration
.inMinutes}:${_NewStopWatchState.duration.inSeconds.remainder(60)}";
});
}
startOrStop() {
if(startStop) {
setState(() {
btnPlayStatus = Icons.pause;
});
startWatch();
} else {
setState(() {
btnPlayStatus = Icons.play_arrow;
});
stopWatch();
}
}
startWatch() {
setState(() {
startStop = false;
watch.start();
timer = Timer.periodic(Duration(milliseconds: 100), updateTimer());
});
}
stopWatch() {
setState(() {
startStop = true;
watch.stop();
setTime();
});
}
setTime() {
var timeSoFar = watch.elapsedMilliseconds;
setState(() {
elapsedTime = transformMilliSeconds(timeSoFar);
});
}
transformMilliSeconds(int milliseconds) {
int hundreds = (milliseconds / 10).truncate();
int seconds = (hundreds / 100).truncate();
int minutes = (seconds / 60).truncate();
String minutesStr = (minutes % 60).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
return "$minutesStr:$secondsStr";
}
}
如果你想要一个带计时器的秒表,你可以使用我的简单 github 项目。
我希望这会对某些人有所帮助。谢谢。