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
相关产品推荐
相关产品推荐

