及时做APP开发实战(六)-番茄钟进度条动态基准实现

及时做APP开发实战(六)-番茄钟进度条动态基准实现

本文将详细介绍番茄钟进度条动态基准的实现,解决自定义时长时进度显示不准确的问题。

一、问题背景

1.1 问题现象

在番茄钟应用中,用户可以自定义专注时长(如15分钟、25分钟、45分钟等)。但进度条始终以固定的25分钟为基准计算进度,导致:

┌─────────────────────────────────────┐ │ 问题现象示意 │ ├─────────────────────────────────────┤ │ 设置15分钟 → 进度最高只能到60% │ │ 设置25分钟 → 进度正常到100% │ │ 设置45分钟 → 进度提前就满了 │ └─────────────────────────────────────┘

1.2 问题分析

**

原代码中进度条计算使用了固定常量:

// 问题代码:固定使用25分钟consttotalTime=Constants.POMODORO_DURATION*60;// 固定25分钟constprogress=((totalTime-this.timeLeft)/totalTime)*100;

问题根源

  • 进度条基准totalTime使用了常量POMODORO_DURATION
  • 没有使用用户设置的自定义时长customDuration
  • 导致进度计算与实际时长不匹配

二、解决方案

2.1 核心思路

┌─────────────────────────────────────┐ │ 解决思路 │ ├─────────────────────────────────────┤ │ 1. 使用动态变量替代固定常量 │ │ 2. 确保所有计算使用同一数据源 │ │ 3. 单位转换:分钟 → 秒 │ └─────────────────────────────────────┘

2.2 代码修改

修改前

// 进度条计算 - 固定使用25分钟consttotalTime=Constants.POMODORO_DURATION*60;constprogress=((totalTime-this.timeLeft)/totalTime)*100;

修改后

// 进度条计算 - 使用自定义时长consttotalTime=this.customDuration*60;// 使用设定的时长constprogress=((totalTime-this.timeLeft)/totalTime)*100;

2.3 完整实现示例

@Entry@Componentstruct PomodoroTimer{@StatecustomDuration:number=25;// 用户设置的时长(分钟)@StatetimeLeft:number=25*60;// 剩余时间(秒)@StateisRunning:boolean=false;privatetimerId:number=-1;build(){Column(){// 进度条Progress({value:this.getProgress(),total:100,type:ProgressType.Ring}).width(200).height(200).color('#FF6B6B')// 时间显示Text(this.formatTime(this.timeLeft)).fontSize(48).fontWeight(FontWeight.Bold)// 时长选择Row(){ForEach([15,25,45],(duration:number)=>{Button(`${duration}分钟`).backgroundColor(this.customDuration===duration?'#FF6B6B':'#E0E0E0').fontColor(this.customDuration===duration?Color.White:'#333333').onClick(()=>{this.customDuration=duration;this.timeLeft=duration*60;})})}.margin({top:20})// 开始按钮Button(this.isRunning?'暂停':'开始').onClick(()=>this.toggleTimer()).margin({top:20})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}// 计算进度百分比getProgress():number{consttotalTime=this.customDuration*60;// 使用动态时长constelapsed=totalTime-this.timeLeft;return(elapsed/totalTime)*100;}// 格式化时间显示formatTime(seconds:number):string{constmins=Math.floor(seconds/60);constsecs=seconds%60;return`${mins.toString().padStart(2,'0')}:${secs.toString().padStart(2,'0')}`;}// 切换计时器状态toggleTimer(){if(this.isRunning){clearInterval(this.timerId);this.isRunning=false;}else{this.isRunning=true;this.timerId=setInterval(()=>{if(this.timeLeft>0){this.timeLeft--;}else{clearInterval(this.timerId);this.isRunning=false;}},1000);}}}

三、效果对比

3.1 功能验证

【修复前后对比图】

场景修改前修改后
设置15分钟进度最高到60%进度可到100% ✅
设置25分钟进度可到100%进度可到100% ✅
设置45分钟进度提前满进度可到100% ✅

3.2 进度计算逻辑

进度百分比 = (已过时间 / 总时间) × 100 其中: - 已过时间 = 总时间 - 剩余时间 - 总时间 = customDuration × 60(分钟转秒)

四、最佳实践

4.1 开发建议

┌─────────────────────────────────────┐ │ 开发建议 │ ├─────────────────────────────────────┤ │ 1. 避免使用硬编码常量 │ │ 2. 使用状态变量实现动态绑定 │ │ 3. 确保计算逻辑与数据源一致 │ │ 4. 注意单位转换(分钟↔秒) │ └─────────────────────────────────────┘

4.2 常见错误

// ❌ 错误:使用固定常量consttotalTime=25*60;// ❌ 错误:单位不一致constprogress=(this.timeLeft/this.customDuration)*100;// ✅ 正确:使用动态变量,单位一致consttotalTime=this.customDuration*60;constprogress=((totalTime-this.timeLeft)/totalTime)*100;

五、总结

本文解决了番茄钟进度条在自定义时长时显示不准确的问题,核心是将固定常量替换为动态状态变量。在开发可配置功能时,务必确保所有相关的计算逻辑都使用动态配置值,这样可以保证功能的一致性和用户体验。