HarmonyOS6 三方库插件实战:RcRate 评分组件交互逻辑与事件处理机制深度解析

张开发
2026/4/10 18:09:19 15 分钟阅读

分享文章

HarmonyOS6 三方库插件实战:RcRate 评分组件交互逻辑与事件处理机制深度解析
文章目录前言一、交互模式总览1.1 三种交互维度1.2 交互优先级链二、点击事件处理2.1 整星点击逻辑2.2 半星点击逻辑三、触摸滑动机制3.1 滑动的二阶段设计3.2 触摸坐标换算四、约束控制机制4.1 最小选中数 rcRateMinCount4.2 可清空 rcRateClearable五、完整示例总结前言一个优秀的评分组件不仅要展示好看更要摸起来顺手。手机场景下用户习惯用拇指滑过星星快速选择或者精确点击半颗星来表达细腻情感。HarmonyOS6RcRate 三方库插件实现了一套完整的触摸交互体系覆盖点击、滑动、半星精确选择等场景。本文将深入拆解其事件处理机制帮助开发者理解每一个交互细节背后的实现原理。一、交互模式总览1.1 三种交互维度RcRate 的交互系统由三个维度构成每个维度均可独立配置维度控制参数默认值说明整体可交互性rcRateDisabledfalse禁用后点击和滑动均无效半星精确点击rcRateAllowHalffalse允许选择 0.5 精度的评分触摸滑动选择rcRateTouchabletrue允许手指滑过快速评分这三个参数的组合可以覆盖从完全只读到滑动半星全功能的所有场景。主要特点rcRateDisabled权限最高优先于其他所有配置rcRateTouchablefalse只禁用滑动点击仍然有效rcRateAllowHalf同时影响点击和滑动的精度1.2 交互优先级链禁用检查rcRateDisabled └── 触摸事件onTouch ├── TouchType.Down → 进入触摸态 ├── TouchType.Move → 计算悬停值需 rcRateTouchable └── TouchType.Up → 确认选值触发 onChange └── 点击事件onClick └── 整星点击 / 半星点击二、点击事件处理2.1 整星点击逻辑handleRcRateClick(index)处理整星点击包含三层判断privatehandleRcRateClick(index:number):void{if(this.rcRateDisabled)return;// 1. 禁用检查letnewValueindex;// 2. 可清空检查点击当前分数 → 清空为 0if(this.rcRateClearablethis.rcRateValueindex){newValue0;}// 3. 最小值检查新值不能低于 minCount但 0 除外if(newValuethis.rcRateMinCountnewValue!0){newValuethis.rcRateMinCount;}// 4. 变化检查值未变时不触发回调if(newValue!this.rcRateValuethis.rcRateOnChange){this.rcRateOnChange(newValue);}}可清空功能rcRateClearable的逻辑是当用户点击已经选中的那颗星时将评分清零。这在可选填的评价场景非常有用。2.2 半星点击逻辑半星点击通过GestureGroup实现与整星点击相互排斥.gesture(GestureGroup(GestureMode.Exclusive,TapGesture().onAction((){if(this.rcRateAllowHalf){this.handleRcRateHalfClick(index);}})))handleRcRateHalfClick将点击的星星 index 减去 0.5 作为新值privatehandleRcRateHalfClick(index:number):void{if(this.rcRateDisabled||!this.rcRateAllowHalf)return;constnewValueindex-0.5;if(newValuethis.rcRateMinCount)return;// 最小值限制if(newValue!this.rcRateValuethis.rcRateOnChange){this.rcRateOnChange(newValue);}}提示GestureMode.Exclusive确保半星手势和整星点击不会同时触发手势系统会根据触摸位置自动选择响应者。三、触摸滑动机制3.1 滑动的二阶段设计触摸滑动采用预览-确认两阶段设计这是流畅交互体验的关键阶段一预览手指按下并滑动时实时更新内部状态rcRateHoverValueUI 同步展示对应分值但不触发onChange。阶段二确认手指抬起TouchType.Up或取消TouchType.Cancel时将悬停值作为最终值触发onChange通知父组件更新。.onTouch((event){if(event.typeTouchType.Down){this.rcRateIsTouchingtrue;// 进入预览态}elseif(event.typeTouchType.Up||event.typeTouchType.Cancel){this.rcRateIsTouchingfalse;// 退出预览态if(this.rcRateTouchablethis.rcRateHoverValue!this.rcRateValue){constnewValuethis.rcRateHoverValue;if(newValuethis.rcRateMinCount||newValue0){this.rcRateOnChange?.(newValue);// 确认提交}}this.rcRateHoverValue0;// 重置悬停值}elseif(event.typeTouchType.Move){constcontainerWidththis.rcRateMax*(this.rcRateSizethis.rcRateGutter);this.handleRcRateTouchMove(event,containerWidth);// 实时计算}})3.2 触摸坐标换算handleRcRateTouchMove将触摸 x 坐标换算为评分值privatehandleRcRateTouchMove(event:TouchEvent,containerWidth:number):void{if(this.rcRateDisabled||!this.rcRateTouchable)return;constxevent.touches[0].x;conststarTotalWidththis.rcRateSizethis.rcRateGutter;// 单星占位宽度letvalueMath.floor(x/starTotalWidth)1;// 整星值// 半星判断触摸点在星星内的左半部分if(this.rcRateAllowHalf){constposInStarx%starTotalWidth;if(posInStarthis.rcRateSize/2){value-0.5;}}// 边界约束valueMath.max(0,Math.min(value,this.rcRateMax));// 最小值约束if(value0valuethis.rcRateMinCount){valuethis.rcRateMinCount;}this.rcRateHoverValuevalue;}坐标换算的核心公式示意starTotalWidth rcRateSize rcRateGutter 24 8 32vp 触摸 x 70vp 整星值 floor(70 / 32) 1 2 1 3 星内位置 70 % 32 6vp 是否半星6 24/212 → 是 → value 3 - 0.5 2.5四、约束控制机制4.1 最小选中数 rcRateMinCountrcRateMinCount实现了一个软下限用户无法将评分降到该值以下但允许清空为 0如果允许的话。这个软下限设计避免了强制评分的尴尬——当用户完全不想评分时0 仍然是合法状态。评分操作minCount2 时的结果点击第 3 颗星值为 3正常点击第 1 颗星值被强制为 2rcRateClearabletrue 时点击当前分值变为 0允许4.2 可清空 rcRateClearable// 启用可清空再次点击当前分值可以归零RcRate({rcRateValue:this.score,rcRateClearable:true,rcRateShowScore:true,rcRateOnChange:(value:number){this.scorevalue;}})典型场景问卷中可选的评分题用户可以取消已选的评分。五、完整示例import{RcRate,RcRateColors}fromrchoui;EntryComponentstruct RcRateInteractionDemo{StatercScore:number3;StatercHalfScore:number2.5;StatercClearScore:number4;StatercMinScore:number0;StatercNoSwipeScore:number2;StatercLastEvent:string等待操作...;build(){Scroll(){Column({space:16}){Text(RcRate 交互机制示例).fontSize(20).fontWeight(FontWeight.Bold).margin({top:8,bottom:4})// 半星 滑动全功能Column({space:12}){Text(全功能半星 滑动选择).fontSize(14).fontColor(#646A73)RcRate({rcRateValue:this.rcHalfScore,rcRateAllowHalf:true,rcRateTouchable:true,rcRateShowScore:true,rcRateActiveColor:RcRateColors.GRADIENT,rcRateLowThreshold:2,rcRateHighThreshold:4,rcRateOnChange:(value:number){this.rcHalfScorevalue;this.rcLastEvent半星评分变化${value};}})Text(可滑动选择也可点击左半部分选半星).fontSize(11).fontColor(#8F959E)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)// 仅点击禁止滑动Column({space:12}){Text(仅点击禁止滑动).fontSize(14).fontColor(#646A73)RcRate({rcRateValue:this.rcNoSwipeScore,rcRateTouchable:false,rcRateShowScore:true,rcRateOnChange:(value:number){this.rcNoSwipeScorevalue;this.rcLastEvent点击评分变化${value};}})Text(滑动无效只能点击星星).fontSize(11).fontColor(#8F959E)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)// 可清空Column({space:12}){Text(可清空再次点击同一颗星归零).fontSize(14).fontColor(#646A73)RcRate({rcRateValue:this.rcClearScore,rcRateClearable:true,rcRateShowScore:true,rcRateActiveColor:RcRateColors.RED,rcRateOnChange:(value:number){this.rcClearScorevalue;this.rcLastEvent可清空评分变化${value};}})Text(当前${this.rcClearScore}点击第${this.rcClearScore}颗星可清空).fontSize(11).fontColor(#8F959E)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)// 最小选中数Column({space:12}){Text(最小选中数 2不能选 1 星).fontSize(14).fontColor(#646A73)RcRate({rcRateValue:this.rcMinScore,rcRateMinCount:2,rcRateShowScore:true,rcRateOnChange:(value:number){this.rcMinScorevalue;this.rcLastEvent带最小值评分变化${value};}})Text(点击第 1 颗星分值会被强制为 2).fontSize(11).fontColor(#8F959E)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)// 只读/禁用Column({space:12}){Text(只读模式禁用所有交互).fontSize(14).fontColor(#646A73)RcRate({rcRateValue:3.5,rcRateDisabled:true,rcRateAllowHalf:true,rcRateShowScore:true,rcRateScoreTemplate:{value} / 5.0})Text(透明度降低点击和滑动均无效).fontSize(11).fontColor(#8F959E)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)// 事件日志Column({space:8}){Text(事件日志).fontSize(14).fontColor(#646A73)Text(this.rcLastEvent).fontSize(13).fontColor(#3370FF).padding(12).width(100%).backgroundColor(#F0F4FF).borderRadius(8)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)Text().height(20)}.padding({left:16,right:16,top:16,bottom:16}).width(100%)}.width(100%).height(100%).backgroundColor(#F5F6F7)}}总结RcRate 的交互体系围绕预览-确认两阶段模型构建触摸滑动时实时更新内部悬停值反馈视觉松手时才触发外部回调。三层参数rcRateDisabled、rcRateTouchable、rcRateAllowHalf独立控制交互权限配合rcRateClearable和rcRateMinCount约束逻辑可以精确满足从严格必填评分到可选清空评分的各类业务场景。

更多文章