在 Flutterd 中,我有一个 int 计时器值,当按下按钮时,该值会抛出到按钮,这样即使应用程序关闭,该值也会继续运行。当我关闭并打开应用程序时,剩余时间将立即以文本形式显示,但我无法做到这一点,如何将计时器保存到本地内存?
我尝试过共享偏好,但我做不到
我用 GetX 在 flutter 中构建了这个功能,让用户在点击奖品后获得奖品,计时器将启动到 24 小时,在用户关闭应用程序并返回后,计时器将从最后一次用户操作开始计时,通过检查我保存到本地存储中的时间并计算保存的时间和 DateTime.now() 之间的差异,这是代码,但我使用 GetStorage 不使用共享首选项:
声明此变量
bool canGetPrize = true;
Stringeta = '';
并在班级初始化时检查用户是否可以获得奖品
void onInit() {
canGetPrize.value = box.read(GetBoxKey.canGetPrize) ?? true;
_loadTimerState();// this function to load state for timer if data saved
show the timer ETA if not view the button to get The prize
super.onInit();
}
构建 _loadTimerState() 函数:
Future<void> _loadTimerState() async {
try {
String? nextPrize = box.read("nextPrizeTime");
if (nextPrize != null) {
DateTime? nextPrizeTime = DateTime.parse(nextPrize);
DateTime now = DateTime.now();
if (now.isAfter(nextPrizeTime)) {
// User can get the prize now
canGetPrize= true;
await box.write("canGetPrize", true);
} else {
// Calculate ETA
_startEtaTimer(nextPrizeTime);
}
}
update();
} catch (e) {
throw Exception("Error Load Timer $e");
}
}
这是当用户单击按钮时获取奖品的函数:
void getPrize() async {
try {
DateTime nextPrizeTime = DateTime.now().add(const Duration(days: 1));
box.write("nextPrizeTime", nextPrizeTime.toString());
canGetPrize= false;
await box.write("canGetPrize", false);
_startEtaTimer(nextPrizeTime);
} catch (e) {
throw Exception("Error Get Prize $e");
}
}
以及此函数中的构建 ETA 计时器
void _startEtaTimer(DateTime targetTime) {
try {
Timer.periodic(const Duration(seconds: 1), (Timer t) async {
DateTime now = DateTime.now();
Duration difference = targetTime.difference(now);
if (difference.isNegative) {
t.cancel();
canGetPrize.value = true;
await box.write(GetBoxKey.canGetPrize, true);
eta.value = '';
box.remove(GetBoxKey.nextPrizeTime);
} else {
eta.value = _formatDuration(difference);
}
});
} catch (e) {
throw Exception("Error Start ETA Timer $e");
}
}
String _formatDuration(Duration duration) {
int hours = duration.inHours;
int minutes = (duration.inMinutes % 60);
int seconds = (duration.inSeconds % 60);
return '$hours:${minutes.toString().padLeft(2,
'0')}:${seconds.toString().padLeft(2, '0')}';
}
在你的 UI 中使用 TimerBuilder 包来构建像这样运行的计时器:
TimerBuilder.periodic(const Duration(seconds: 1),
builder: (context) {
return Obx(() {
return Visibility(
visible: !controller.canGetPrize &&
controller.eta.isNotEmpty,
child: Text(
'prize After : ${controller.eta}',
style:
TextStyle(fontSize: 20, color: AppColor.primaryColor),
),
);
});
}),