You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何存储首次点击DateTime实现1小时内最多触发5次激励视频

问题核心原因

现有代码的问题集中在变量作用域和存储逻辑错误:

  • 你将计数变量count和时间变量now声明在了点击事件的回调内部,每次触发点击都会重置这两个变量,自然无法累计次数、也无法记录真实的首次点击时间
  • 没有做持久化存储的话,就算把变量提升到全局/类成员,APP重启后数据就会清空,规则也会失效
实现方案

内存级实现(APP运行期间有效)

把计数和首次点击时间变量提升到业务类的成员位置,不要写在点击回调内部:

// 放到State类/对应业务类的成员位置,不要声明在点击回调内部
int _rewardClickCount = 0;
DateTime? _firstRewardClickTime;

// 点击事件的回调方法
void onRewardClick() async {
  final now = DateTime.now();
  // 首次点击时初始化时间和计数
  if (_firstRewardClickTime == null) {
    _firstRewardClickTime = now;
    _rewardClickCount = 0;
  }
  // 计算和首次点击的时间差
  final diff = now.difference(_firstRewardClickTime!);
  // 超出1小时就重置周期,重新计数
  if (diff.inMinutes >= 60) {
    _firstRewardClickTime = now;
    _rewardClickCount = 0;
  }
  // 次数没到上限才走激励视频逻辑
  if (_rewardClickCount < 5) {
    bool isRewardedVideoAvailable = await FlutterApplovinMax.isLoaded(listener);
    if (isRewardedVideoAvailable) {
      FlutterApplovinMax.showRewardVideo((AppLovinAdListener event) => listener(event));
      // 计数触发时机可按业务调整:点击就计数写在这里,播放完成才计数就写到广告完成回调里
      _rewardClickCount++;
      print("points${points.toString()}");
      print("idok$_rewardClickCount");
    }
  } else {
    // 超出次数的提示逻辑,比如弹窗提示"1小时内最多可观看5次激励视频"
  }
}

持久化实现(APP重启依然生效)

如果要求APP退出后再打开规则依然生效,用shared_preferences把首次点击时间和计数存到本地即可,核心逻辑如下:

// 点击时先读取本地存储的记录
final prefs = await SharedPreferences.getInstance();
final String? storedFirstTimeStr = prefs.getString('first_reward_click_time');
final int storedCount = prefs.getInt('reward_click_count') ?? 0;

DateTime? firstClickTime = storedFirstTimeStr != null ? DateTime.parse(storedFirstTimeStr) : null;
final now = DateTime.now();
// 首次点击或者超出1小时就重置周期
if (firstClickTime == null || now.difference(firstClickTime).inMinutes >= 60) {
  firstClickTime = now;
  await prefs.setString('first_reward_click_time', firstClickTime.toIso8601String());
  await prefs.setInt('reward_click_count', 0);
  _rewardClickCount = 0;
} else {
  _rewardClickCount = storedCount;
}

// 后续次数判断和广告播放逻辑和内存版一致,计数变动后同步更新到本地存储
if (_rewardClickCount <5) {
  // 原有激励视频播放逻辑
  _rewardClickCount++;
  await prefs.setInt('reward_click_count', _rewardClickCount);
}
注意事项
  • 计数触发时机可灵活调整:如果要求点击就算次数,把计数逻辑放到_rewardClickCount < 5判断之后立刻执行即可;如果要求成功播放完成才算次数,就把计数逻辑放到广告播放完成的回调里
  • 时间判断精度可按需调整,要更高精度的1小时判断可以把inMinutes >=60改成inSeconds >= 3600

内容的提问来源于stack exchange,提问作者James Threepat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 14:24:05