Flutter日期倒计时问题:天数显示错误与计时速度异常
Flutter倒计时器问题修复
问题原因分析
- 天数显示错误:原代码计算天数时多了
%24,导致超过24天的数值被取模,无法正确显示真实剩余天数。 - 计时速度过快:Timer在
build方法中创建,每次setState都会生成新的Timer实例,多个Timer同时触发减1操作,导致计时速度异常;同时未在dispose中销毁Timer,存在内存泄漏风险。
修复后的完整代码
import 'dart:async'; import 'package:flutter/material.dart'; class Time extends StatefulWidget { const Time({Key? key}) : super(key: key); @override State<Time> createState() => _TimeState(); } final eventTime = DateTime.parse('2024-01-10 03:41:00'); class _TimeState extends State<Time> { static const duration = Duration(seconds: 1); late int timeDiff; late Timer timer; bool isActive = true; void handleTick() { if (isActive) { setState(() { final diff = eventTime.difference(DateTime.now()); if (diff.isNegative) { timeDiff = 0; print('Times up!'); timer.cancel(); // 添加倒计时结束后的操作 } else { timeDiff = diff.inSeconds; } }); } } @override void dispose() { timer.cancel(); // 销毁Timer,避免内存泄漏 super.dispose(); } @override void initState() { super.initState(); // 初始化时计算初始时间差,确保数值非负 timeDiff = eventTime.difference(DateTime.now()).inSeconds.clamp(0, double.infinity).toInt(); // 在initState中创建Timer,确保只初始化一次 timer = Timer.periodic(duration, (Timer t) { handleTick(); }); } @override Widget build(BuildContext context) { int days = timeDiff ~/ (24 * 60 * 60); // 移除多余的%24,正确计算总天数 int hours = timeDiff ~/ (60 * 60) % 24; int minutes = (timeDiff ~/ 60) % 60; int seconds = timeDiff % 60; return Scaffold( appBar: AppBar( backgroundColor: const Color(0x00fafafa), elevation: 0, leading: const BackButton(color: Colors.deepOrange,), ), body: SingleChildScrollView( child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ LabelText( label: 'DAYS', value: days.toString().padLeft(2, '0')), LabelText( label: 'HRS', value: hours.toString().padLeft(2, '0')), LabelText( label: 'MIN', value: minutes.toString().padLeft(2, '0')), LabelText( label: 'SEC', value: seconds.toString().padLeft(2, '0')), ], ), ], ), ) ); } } class LabelText extends StatelessWidget { const LabelText({super.key, required this.label, required this.value}); final String label; final String value; @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 5), padding: const EdgeInsets.all(20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(25), color: Colors.grey, ), child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Text( value, style: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold), ), Text( label, style: const TextStyle( color: Colors.white70, ), ), ], ), ); } }
关键修复点
- 天数计算:移除天数公式中的
%24,直接通过总秒数除以一天的秒数得到真实剩余天数。 - Timer生命周期管理:将Timer初始化移至
initState,确保仅创建一个实例;在dispose中销毁Timer,避免内存泄漏。 - 时间差准确性优化:每次计时触发时重新计算当前时间与目标时间的差值,避免Timer延迟导致的累计误差,同时处理倒计时结束的逻辑。
内容的提问来源于stack exchange,提问作者user17657114
相关产品推荐
相关产品推荐

