mine_trial_membership_countdown_text.dart 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:location/utils/common_expand.dart';
  5. import '../../data/bean/member_status_info.dart';
  6. import '../../resource/string.gen.dart';
  7. class MineTrialMembershipCountdownText extends StatefulWidget {
  8. final MemberStatusInfo? memberStatusInfo;
  9. final VoidCallback? trialHasExpiredCallBack;
  10. const MineTrialMembershipCountdownText({
  11. super.key,
  12. this.memberStatusInfo,
  13. this.trialHasExpiredCallBack
  14. });
  15. @override
  16. State<MineTrialMembershipCountdownText> createState() => _MineTrialMembershipCountdownTextState();
  17. }
  18. class _MineTrialMembershipCountdownTextState extends State<MineTrialMembershipCountdownText> {
  19. Timer? _timer; // 使用可空类型,初始化为null
  20. String _countdownText = '';
  21. bool _isCountdownActive = false; // 标记倒计时是否活跃
  22. @override
  23. void initState() {
  24. super.initState();
  25. _initParameter();
  26. }
  27. @override
  28. void didUpdateWidget(covariant MineTrialMembershipCountdownText oldWidget) {
  29. super.didUpdateWidget(oldWidget);
  30. // 检查memberStatusInfo是否有变化
  31. if (widget.memberStatusInfo != oldWidget.memberStatusInfo) {
  32. DateTime endTime = DateTime.fromMillisecondsSinceEpoch(widget.memberStatusInfo!.trialEndTimestamp ?? 0);
  33. Duration remaining = endTime.difference(DateTime.now());
  34. if (!_isCountdownActive) {
  35. _resetTimer();
  36. _initParameter();
  37. }
  38. }
  39. }
  40. void _initParameter() {
  41. // 清除现有计时器
  42. _resetTimer();
  43. // 创建倒计时定时器
  44. if (widget.memberStatusInfo?.trialed == true) {
  45. // 计算剩余时间
  46. DateTime endTime = DateTime.fromMillisecondsSinceEpoch(widget.memberStatusInfo!.trialEndTimestamp ?? 0);
  47. Duration remaining = endTime.difference(DateTime.now());
  48. if (remaining.inSeconds > 0) {
  49. print("创建新的倒计时定时器");
  50. // 创建每秒更新一次的定时器
  51. _timer = Timer.periodic(const Duration(seconds: 1), (_) => _countdownisInProgress());
  52. _isCountdownActive = true;
  53. _updateTime();
  54. _countdownisInProgress();
  55. } else {
  56. _countdownText = StringName.memberTrialHasExpired;
  57. }
  58. } else {
  59. // 将时间戳转换为DateTime(根据单位处理)
  60. _countdownText = StringName.memberExperienceVip;
  61. }
  62. }
  63. void _resetTimer() {
  64. // 取消现有计时器并重置状态
  65. _timer?.cancel();
  66. _timer = null;
  67. _isCountdownActive = false;
  68. }
  69. void _updateTime() {
  70. // 将时间戳转换为DateTime(根据单位处理)
  71. _countdownText = StringName.memberExperienceVip;
  72. if ((widget.memberStatusInfo?.trialed ?? false)) {
  73. DateTime endTime = DateTime.fromMillisecondsSinceEpoch(widget.memberStatusInfo!.trialEndTimestamp ?? 0);
  74. Duration remaining = endTime.difference(DateTime.now());
  75. ///正在使用
  76. if (remaining.inSeconds > 0) {
  77. if (!_isCountdownActive) {
  78. _countdownisInProgress();
  79. }
  80. } else {
  81. //已经使用完了
  82. _resetTimer();
  83. _countdownText = StringName.memberTrialHasExpired;
  84. }
  85. } else {
  86. // 未试用或其他状态
  87. _resetTimer();
  88. }
  89. setState(() {});
  90. }
  91. /// 正在倒计时
  92. void _countdownisInProgress() {
  93. // 检查时间戳是否为空
  94. _countdownText = StringName.memberExperienceVip;
  95. // 将时间戳转换为DateTime(根据单位处理)
  96. final timestamp = widget.memberStatusInfo!.trialEndTimestamp!;
  97. DateTime endTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
  98. Duration remaining = endTime.difference(DateTime.now());
  99. //print("倒计时状态---${widget.memberStatusInfo!.trialEndTimestamp}---:${remaining.inSeconds}---${remaining.inSeconds <= 0}---:${DateTime.now()}---:${endTime}");
  100. if (widget.memberStatusInfo?.trialed == true) {
  101. if (remaining.inSeconds == 0) {
  102. _resetTimer(); // 取消计时器并重置状态
  103. _countdownText = StringName.memberTrialHasExpired;
  104. setState(() {});
  105. if (widget.trialHasExpiredCallBack != null) {
  106. widget.trialHasExpiredCallBack!();
  107. }
  108. } else {
  109. //已经使用完了
  110. _countdownText = _formatDuration(remaining);
  111. _countdownText = '${StringName.memberCountdownRemaining} ${_countdownText} ${StringName.memberCountdownExperienceTime}';
  112. if (mounted) {
  113. setState(() {});
  114. }
  115. }
  116. } else {
  117. _resetTimer();
  118. _countdownText = StringName.memberExperienceVip;
  119. if (mounted) {
  120. setState(() {});
  121. }
  122. }
  123. }
  124. String _formatDuration(Duration duration) {
  125. String twoDigits(int n) => n.toString().padLeft(2, '0');
  126. String hours = twoDigits(duration.inHours);
  127. String minutes = twoDigits(duration.inMinutes.remainder(60));
  128. String seconds = twoDigits(duration.inSeconds.remainder(60));
  129. return '$hours:$minutes:$seconds';
  130. }
  131. @override
  132. void dispose() {
  133. _resetTimer(); // 使用统一的方法清理计时器
  134. super.dispose();
  135. }
  136. @override
  137. Widget build(BuildContext context) {
  138. return Text(
  139. _countdownText,
  140. style: TextStyle(
  141. fontSize: 13.sp,
  142. color: "#8A5F03".color,
  143. fontWeight: FontWeight.bold
  144. )
  145. );
  146. }
  147. }