HarmonyOS7 CustomStarCount 教程:同一个评分控件,怎么做 3 星、5 星、10 星 📅 2026/7/16 4:10:53 文章目录前言先看这个案例到底实现了什么为什么评分颗数不能随便定先抓住页面里的 3 个核心状态为什么这里要分成 3 个状态先看完整代码stars() 才是这篇最关键的配置为什么这件事很重要rating: this.xxx 让每组评分都读自己的结果indicator: false 说明现在是输入态不是展示态onChange 让 3 组评分都真正活起来右边那行 2/3、3.5/5、7/10 为什么很有必要为什么 3.5/5 这种结果也值得你注意这篇最值得记住的 4 件事1. stars() 改的是评分规则不只是外观2. 不同评分规则最好拆成不同状态3. onChange 是评分结果进入状态的入口4. 数字回显能明显提升理解成本小白最容易踩的坑1. 只想着改星星数量没想评分场景适不适合2. 多组评分共用一个状态3. 星星能点但没有明确结果回显4. 把输入态和展示态混为一谈这篇代码怎么继续改成真实业务动手改一改写在最后前言很多刚学 HarmonyOS7 的同学第一次接触Rating时会默认觉得评分就是 5 颗星。这其实是最常见的一种设计但不是唯一答案。真实业务里不同页面对评分颗数的要求经常不一样。比如有些场景只想让用户做简单判断用 3 星就够了有些页面希望保留常见习惯就用 5 星还有些更强调区分度可能会做成 10 星制。所以这篇文章真正要讲清楚的不是“评分控件能不能改颗数”而是当评分规则变了页面应该怎么跟着一起设计。你把这篇吃透后面再做商品评价、内容打分、门店评分、服务满意度这类页面思路会稳很多。先看这个案例到底实现了什么这个页面把同一个Rating控件做成了 3 种评分规则3星评分5星评分10星评分每一组评分后面都有一行实时变化的结果文案比如2/33.5/57/10这说明这个案例不是单纯在展示不同颗数效果而是在做一件更重要的事让不同评分规则都能形成完整的“用户点击 - 状态变化 - 结果回显”闭环。这也是为什么它虽然看起来只是一个基础案例但其实很值得认真读。为什么评分颗数不能随便定先别急着看代码先想业务。3 星、5 星、10 星看起来只是数字不同背后表达的意思其实不一样。评分规则更适合什么场景原因3 星简单满意度、快速反馈用户决策成本低点起来快5 星商品评价、服务评分用户熟悉接受度最高10 星影视打分、内容细分评分区分度更高能表达更细的差异也就是说评分颗数不是单纯的 UI 配置它本质上是在决定“这个页面希望用户给出多细的判断”。如果你做的是一个非常轻量的反馈页3 星通常就够了如果是电商、外卖、酒店这种大众熟悉的评分场景5 星往往最自然如果你需要更细的层级区分10 星会更合适。所以你学这篇时最好别只记住.stars(3)、.stars(5)、.stars(10)这些写法更重要的是记住评分规则应该服务于业务判断不是越多越高级。先抓住页面里的 3 个核心状态这个案例最关键的状态是这几行Staterating3:number2Staterating5:number3.5Staterating10:number7它们分别保存三种评分规则下的当前结果rating33 星评分当前值rating55 星评分当前值rating1010 星评分当前值你可以把它们理解成三份独立的“评分结果仓库”。用户点哪一组星星就更新哪一组状态状态一变化对应的文本结果也会跟着更新。为什么这里要分成 3 个状态因为这 3 组评分本来就是 3 套不同规则。它们的上限不一样结果展示方式也不一样后面如果接真实业务提交逻辑、解释文案、标签映射也可能不一样。如果你硬把它们塞进同一个状态里后面只会越来越绕。所以这里分开存不是为了凑代码量而是为了让每一组评分都有自己清楚、独立的结果来源。这也是做交互页面时很重要的一个习惯只要规则不同、意义不同、展示不同就优先拆成独立状态。先看完整代码先把完整代码读一遍后面逐段讲时更容易对上/** * CustomStarCount - Rating 自定义星星数 */import{PRESET_COLORS,generateListItems,PAGE_BG_COLOR,PANEL_BG_COLOR,ACCENT_COLOR,MUTED_TEXT_COLOR}from./typesEntryComponentstruct CustomStarCount{StateisShow:booleantrueStaterating3:number2Staterating5:number3.5Staterating10:number7build(){Column(){if(this.isShow){Scroll(){Column(){Text(Rating 自定义星星数).fontSize(16).fontWeight(FontWeight.Bold).margin({bottom:16})Text(3 星评价).fontSize(14).fontWeight(FontWeight.Medium).margin({bottom:8})Row({space:10}){Rating({rating:this.rating3,indicator:false}).stars(3).onChange((v:number){this.rating3v})Text(${this.rating3}/3).fontSize(14).fontColor(ACCENT_COLOR)}.margin({bottom:16})Text(5 星评价默认).fontSize(14).fontWeight(FontWeight.Medium).margin({bottom:8})Row({space:10}){Rating({rating:this.rating5,indicator:false}).stars(5).onChange((v:number){this.rating5v})Text(${this.rating5}/5).fontSize(14).fontColor(ACCENT_COLOR)}.margin({bottom:16})Text(10 星评价).fontSize(14).fontWeight(FontWeight.Medium).margin({bottom:8})Row({space:10}){Rating({rating:this.rating10,indicator:false}).stars(10).onChange((v:number){this.rating10v})Text(${this.rating10}/10).fontSize(14).fontColor(ACCENT_COLOR)}}.width(100%).padding(16).backgroundColor(PANEL_BG_COLOR).borderRadius(12)}}Text(Rating 自定义星星数 - stars(3/5/10)).fontSize(12).fontColor(MUTED_TEXT_COLOR).margin({top:12})}.width(100%).height(100%).backgroundColor(PAGE_BG_COLOR).padding(16)}}stars()才是这篇最关键的配置先看下面这几行.stars(3).stars(5).stars(10)它们的作用很直接就是指定当前评分控件显示多少颗星。如果你把它翻成大白话就是这一组评分只给 3 个可选位置这一组评分给 5 个可选位置这一组评分给 10 个可选位置这也就意味着控件本身的评分范围会跟着变化。为什么这件事很重要因为评分颗数一变用户的预期也会变。比如看到 3 星用户会倾向于做比较粗的判断看到 5 星用户会认为这是标准评分看到 10 星用户会预期自己能打得更细所以.stars()改的不是一个无关紧要的视觉细节而是在改这个输入控件“允许用户表达多细”。rating: this.xxx让每组评分都读自己的结果再看这里Rating({rating:this.rating3,indicator:false})Rating({rating:this.rating5,indicator:false})Rating({rating:this.rating10,indicator:false})这几行说明每一个评分控件都不是自己偷偷保存结果而是去读页面里的状态。也就是说3 星组件读rating35 星组件读rating510 星组件读rating10这是一种很稳的写法。因为页面里后面所有和这组评分相关的内容比如结果文本、标签文案、提交参数都可以继续围绕同一个状态展开不容易乱。indicator: false说明现在是输入态不是展示态每组评分里都写了indicator:false这一点和前一篇StarRatingBasic是一脉相承的。它的意思是当前这组星星是可以点击、可以修改的它不是只读展示。这点很重要。因为评分控件在真实业务里通常会有两种身份输入态用户自己打分展示态页面只显示已有分数这一篇显然是第一种所以才需要可交互模式。如果你后面做商品详情页、评论列表页很多时候反而更接近展示态。别把这两种语义混在一起。onChange让 3 组评分都真正活起来看这三行.onChange((v:number){this.rating3v}).onChange((v:number){this.rating5v}).onChange((v:number){this.rating10v})这就是整个页面真正发生交互的地方。它们做的事情完全一样用户点击某一组星星。新的评分值通过回调传进来。把这个值写回对应状态。对应的文本结果自动刷新。如果没有这一步会发生什么页面上的星星可能看起来能点但点完以后结果不会真正留在状态里右侧的数字文案也不会同步更新。所以你可以把onChange理解成一句话用户操作的结果必须通过回调写回状态页面才算真的连起来了。右边那行2/3、3.5/5、7/10为什么很有必要很多初学者会觉得既然有星星右边的数字是不是可以不要能不要但不建议。因为星星更偏视觉感受数字更偏明确结果。像下面这些文案Text(${this.rating3}/3)Text(${this.rating5}/5)Text(${this.rating10}/10)它们承担的是结果回显职责。用户点完以后不需要自己数星星就能马上知道当前结果是多少。这一点在 10 星评分里尤其重要。因为星星一多用户更不容易快速确认自己到底点到了哪一档。所以你以后做多星级评分页面时最好尽量保留这种数字反馈。为什么3.5/5这种结果也值得你注意这里默认值里有一行Staterating5:number3.5这说明评分结果不一定只能是整数。这一点很值得你留意因为很多人一提到评分就默认只会想到1、2、3、4、5这种整分。但在真实业务里半星、浮点评分其实很常见比如商品综合评分4.5餐厅评分3.8内容推荐度8.5/10所以当你设计评分页面时除了想“总共几颗星”还要顺手想一件事这个页面的评分精度到底要做到什么程度。这篇最值得记住的 4 件事1.stars()改的是评分规则不只是外观改星星数量本质上是在改用户能表达多细的判断。2. 不同评分规则最好拆成不同状态3 星、5 星、10 星各自有自己的上限和意义分开存更清楚。3.onChange是评分结果进入状态的入口没有回调写回评分就只是表面交互。4. 数字回显能明显提升理解成本尤其在 10 星这种颗数较多的场景里数字结果非常有必要。小白最容易踩的坑1. 只想着改星星数量没想评分场景适不适合不是所有页面都适合 10 星。如果只是一个简单满意度调查星星太多反而会让用户犹豫更久。2. 多组评分共用一个状态这样很容易出现一组点击后另一组展示也被带乱的情况。规则不同的评分尽量分开管理。3. 星星能点但没有明确结果回显特别是星星数量一多用户不一定愿意自己数。给一个清晰的分数字符串体验会好很多。4. 把输入态和展示态混为一谈你要先想清楚这组星星到底是让用户输入还是拿来展示已有结果。这两种页面虽然都用Rating但语义完全不同。这篇代码怎么继续改成真实业务如果你想把这个案例继续往业务里走可以试这些方向方向改法商品评价页保留 5 星评分在下面加评论输入框满意度调查把 3 星评分改成“不满意 / 一般 / 满意”文案映射影视内容评分保留 10 星评分并补充评分说明后台评分规则配置页把 3/5/10 星并排列出来做成规则对比界面你会发现真正一接业务评分颗数就不只是“UI 选择”而是会直接影响页面文案、标签、提交逻辑和用户理解成本。动手改一改建议你自己顺手做 4 个小练习把 3 星评分改成“差 / 中 / 好”三档文案。给 5 星评分增加一个描述比如4.5 分 很满意。把 10 星评分改成电影评分页样式。增加一个提交按钮把三组评分打印出来对比它们的实际结果。这些练习都不复杂但很适合帮你把“评分规则”和“页面设计”真正连起来。写在最后这篇案例最有价值的地方不是告诉你Rating可以改成几颗星而是让你理解评分颗数本身就是交互规则的一部分它会直接影响用户怎么判断、页面怎么表达、结果怎么展示。如果你是 HarmonyOS7 初学者我建议你别只停在把代码跑起来而是亲手把 3 星、5 星、10 星分别改成 3 个你能说得出业务名字的页面。等你能把“控件颗数”翻译成“产品场景”这类基础评分页面你就真的掌握了。