我试图显示一个计时器(格式为dd HH mm ss)以计算每个动作(例如按钮动作)之间的时间。并且需要工作,即使应用程序已关闭并重建。当前,当我按下一个按钮时,我加载了使用sharedpreference保存的字符串日期,该日期代表按下按钮的时间。我格式化所有时间小数点以进行比较并显示时差。我认为它不是很漂亮,不是我要搜索的内容,并且我没有成功以(dd HH mm ss)格式显示时钟。如果有人有一个更简单的例子:)
load_records_pulsion() async{
/*var current_time = DateFormat('yyyy-MM-dd HH').format(DateTime.now());*/
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
RegExp regExp = new RegExp( //Here is the regex time pulsion
r"([12]\d{3})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])",
);
last_pulsion = (prefs.getString('last_pulsion'))??0;
var match = regExp.firstMatch("$last_pulsion");
annees = match.group(1); // hh:mm
mois = match.group(2); // hh:mm
jours = match.group(3); // hh:mm
int annees_int = int.tryParse("$annees") ;
int mois_int = int.tryParse("$mois") ;
int jours_int = int.tryParse("$jours") ;
print("$annees_int");
print("$mois_int");
print("$jours_int");
final last_pulsion2 = DateTime(annees_int, mois_int, jours_int);
final date_now = DateTime.now();
difference_pulsion = date_now.difference(last_pulsion2).inDays;
if(difference_pulsion==0){
difference_pulsion ="";
prefix_pulsion ="Aujourd'hui";
}else{
prefix_pulsion ="jours";
}
});
}
我也尝试了这段代码,没关系,当我调用该函数时,计时器增加了,但是我不想要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";
}
}
答案 0 :(得分:1)
如果您希望计数器在关闭应用程序后仍然存在,则无法将值保存在某个位置(如共享首选项)。
使用dateTime.toIso8601String()和DateTime.parse()将使保存和加载变得不那么难看。 要计算经过的时间,可以使用DateTime.now()。difference(lastButtonPressed)
应该有一个格式化持续时间(https://api.flutter.dev/flutter/intl/DateFormat/formatDurationFrom.html)的函数,但尚未实现。我在这里找到一个:Formatting a Duration like HH:mm:ss
这是一个小例子:
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";
}
}