在flutter中将定时器保存到本地内存

问题描述 投票:0回答:1

在 Flutterd 中,我有一个 int 计时器值,当按下按钮时,该值会抛出到按钮,这样即使应用程序关闭,该值也会继续运行。当我关闭并打开应用程序时,剩余时间将立即以文本形式显示,但我无法做到这一点,如何将计时器保存到本地内存?

我尝试过共享偏好,但我做不到

flutter sharedpreferences flutter-timer
1个回答
0
投票

我用 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),
              ),
            );
          });
        }),
© www.soinside.com 2019 - 2024. All rights reserved.