023 - Rating 评分组件

本文配套演示工程见同目录 ohos/,包含五个可运行的 ArkTS 原生示例,覆盖基础评分、半星支持、商品评价(提交闭环)、历史评分展示、样式定制。所有示例均在 DevEco Studio + 模拟器验证通过。

1. 引言:五颗星星的重量

买东西前,你会先看什么?大概率是那个"4.8 分"和它旁边的一排星星。一条好评是普通人的主观感受,但一万条好评聚在一起,就成了一家店的信用。评分(Rating)大概是电商体系里"性价比"最高的组件——用户只需要点五下,商家就得到了一个可量化、可比较、可排序的质量信号。

评分之所以用星星,是人类几百年的共识:星级是"质量"的通用语言,酒店、电影、App、外卖,全世界都在用五颗星表达"这东西好不好"。它把复杂的质量感知压缩成 0~5 的整数(或半星),输入成本极低,信息密度极高。

在鸿蒙(HarmonyOS)的 ArkUI 声明式框架里,Rating 是"评分型"基础组件:一排星星,点击或拖动即改值,回调一个 0~stars 的数值。它有两种面孔——输入(用户打分)与展示(只读平均分),由 indicator 一个布尔值切换。理解 Rating,关键在于理解它交付的是数值、表达的是意愿:评分的值只是一个信号,商家看的是它的统计量。本文就从这排星星出发,把"能点"讲到"点得准、点得美、点得稳"。

1.1 Rating 在评价体系里的位置

评价类组件不止评分一种,把评价家族摆在一起,Rating 的边界才清楚:

组件 语义 输入方式 典型场景
Rating 星级打分 点/拖星星 商品评价、服务打分
TextArea 文字评价 键盘输入 评价详情、晒单
Toggle 好评/差评 开关二态 一键点赞、踩
Select 选项评价 下拉选择 评价标签选择

可以看到:Rating 负责"量"(打几分),TextArea 负责"质"(说了什么),Toggle 负责"方向"(好还是坏)——三者拼起来就是完整的评价闭环。多数场景的默认组合是"评分 + 文字",星级在前、文字在后,因为分值易统计、文字见真心

1.2 心智模型:一排有刻度的星星

Rating 拆开看,它就四样东西:

  • rating,当前评分,范围 0 ~ stars
  • 刻度stars(星星总数)与 stepSize(步进精度)共同决定"能打出什么分";
  • 面孔indicatorfalse 可打分、true 只读展示;
  • 反馈onChange,打分后回调数值。

四者的关系一句话:stars 定范围,stepSize 定精度,indicator 定面孔,onChange 定结果。把评分想成一把"只有星星刻度的尺子"——量程是星星数,最小刻度是 stepSize,用户每点一下,尺子就读出一个数。

1.3 一次打分发生了什么

用户在星星上点一下或拖动,框架做三件事:命中换算(把点击位置折算成 0~stars 的原始值)→ 精度吸附(按 stepSize 就近取整)→ 事件上报(onChange(value))。换算这一步值得记:设星星排宽 W、点击横坐标 x、星星数 S,原始值大致是:

vraw=xW×S v_{raw} = \frac{x}{W} \times S vraw=Wx×S

再按 stepSize 吸附成最终值。stepSize = 0.5 时 3.2 会吸附到 3.0 或 3.5,stepSize = 1 时只会是整数。stepSize 是评分精度的唯一开关——它决定用户能不能表达"3.5 分"这种中间意愿,后文 4.2 专门演示。

1.4 为什么评分是电商的"信任基础设施"

下单前看评分,本质上是在做一次"用别人的经验降低自己风险"的决策。评分组件把这个决策成本压到最低:一眼扫到数字、二眼看到星数、三眼滚到评价。它之所以成为电商标配,是因为它同时满足了三个角色:用户要快(点五下结束)、商家要准(千条评分统计出稳定均值)、平台要公(同量纲可比、可排序)。理解 Rating,等于理解了"信任是怎么被量化的"。本文就从这排星星的 API 出发,把"能点"讲到"点得准、点得美、点得稳"。

五颗星星是「质量」的通用语言:点五下,全世界都懂。

2. 环境准备

本文基于以下环境:

  • DevEco Studio 5.0 及以上
  • HarmonyOS SDK API 12(5.0.0)
  • 模拟器:Phone(API 12)

演示工程目录结构:

ohos/
├── AppScope/                 # 应用级配置
├── entry/                    # 入口模块
│   └── src/main/ets/
│       ├── entryability/EntryAbility.ets
│       ├── pages/Index.ets
│       ├── model/            # 历史评分数据模型
│       └── components/       # 五个演示组件
└── oh-package.json5          # 模块依赖

说明:本文属于"通用版 HarmonyOS 原生"系列,示例以模拟器验证即可;若你使用 Flutter 专属版(需鸿蒙真机而非模拟器),请注意对应部署差异。

关于运行环境再补两点,避免新手卡在"跑不起来":

  • 签名:模拟器调试可用 DevEco Studio 自动生成的调试证书;真机运行需在 Signing Configs 里配好指纹与 p12/cer/p7b 文件。本文演示工程 module.json5 无特殊敏感权限,跑示例足够。
  • 资源占位:编译需 AppScope/resources/base/media/app_icon.pngentry/.../media/icon.png 两张图标。文章正文统一约定为占位资源,请自行放入对应 PNG;其余示例均为纯文本/色块/表情符号,不依赖额外图片。

这两步到位后,用 DevEco Studio 打开本 ohos/ 目录直接运行 entry 模块即可看到五个演示页。


3. 核心 API 逐层拆解

3.1 值与刻度:rating / stars

Rating 的构造参数只有两个,但语义要掰开:

Rating({ rating: 3.5, indicator: false })
  .stars(5)        // 星星总数,默认 5
  .stepSize(0.5)   // 步进精度,默认 0.5
  • rating:当前评分,取值范围 0 ~ stars。它是"真相源",由 @State 托管,onChange 回写;
  • stars:星星总数,等于"满分的刻度"。默认 5 是全球惯例,特殊场景(如"10 分制")可改;
  • stepSize:取值精度,默认 0.5。它决定"能不能打半星"——设 1 就只有整星,设 0.1 甚至可以打出 4.8 星。

三者合成一句:rating 是当前值、stars 是满分、stepSize 是精度。改 stars 会同时改变值域(10 星制下 6 星才算及格线),改 stepSize 只影响吸附粒度,两者独立。

3.2 精度吸附:stepSize 的取舍

stepSize 的选择是个产品决策,直接决定用户能表达多细的意愿:

stepSize 可表达的值 适合场景
1 0~5 整数 粗粒度打分(满意度 1-5 档)
0.5 0~5 每半星 电商评价、服务评分(主流)
0.1 0~5 任意小数 只读展示细腻均分(4.8 星)

注意一个细节:stepSize 也影响只读展示。历史平均分 4.8 这种小数,若 stepSize = 1 只会显示 5 星全亮(4.8 吸附到 5),失真;配 stepSize = 0.1 才能让 4.8 星精确点亮四星半。所以"展示均分"的场景,stepSize 要调小——这是评分组件最容易踩的展示失真坑(6.2 详述)。

3.3 面孔切换:indicator

indicator 决定 Rating 是"输入"还是"展示":

Rating({ rating: this.rating, indicator: false })  // 可打分(默认)
Rating({ rating: 4.7, indicator: true })           // 只读展示
  • indicator = false(默认):星星可点可拖,onChange 生效;
  • indicator = true:星星只读,任何点击无效,onChange 不触发——商品列表、详情页的平均分展示就是这个面孔。

一个实用技巧:提交后的"锁定"也可以靠它。用户打完分、点完提交,把 indicatorfalse 翻成 true,评分区瞬间从"可编辑"变成"只读"(4.3 的提交闭环就这么做),比"禁用点击 + 置灰"的 DIY 方案省一整段代码。

3.4 反馈事件:onChange

Rating 只有一个事件,签名极简:

.onChange((value: number) => {
  this.rating = value;   // 回写当前值
})

要点:回调参数是吸附后的最终值(已按 stepSize 取整),直接用即可,别再加工。评分没有"拖动过程 vs 松手"的阶段区分——点一下触发一次、拖动过程中持续触发。想做"拖动实时预览 + 松手确认"的反馈,直接用回调值驱动 UI 即可,不必分阶段。

3.5 样式定制:三色体系与尺寸

Rating 的视觉由"三色 + 尺寸"定制:

Rating({ rating: this.rating })
  .starColor('#FFB800')             // 已评星星颜色
  .secondaryColor('#E0E0E0')        // 未评星星颜色
  .starBackgroundColor('#F0F4FA')   // 星星底色(可选)
  .width(200)                       // 整排宽度(星星自动等分)
  .height(40)                       // 星星高度

要点:

  • starColor 管"已评"、secondaryColor 管"未评":一对对比色让"点亮了几颗"一目了然,金色 + 浅灰是最高频组合;
  • 宽高即星星大小:整排宽度按星星数等分,width(200) + 5 星 = 每颗 40 宽。想换星星图案,用 starStyle 传自定义图片资源($r 引用),演示工程用颜色体系,接入真实业务时换资源即可。

配色原则就一条:已评要亮、未评要淡、对比要鲜明。评分区是用户"眼动交互"的高频区域,对比弱了,扫一眼看不出 4 星和 5 星的区别,信任感就淡了。

3.6 与兄弟组件的取舍再强调

回顾 1.1 的表格,把评价输入的选择判据收成三句话:

  • 星级量化Rating
  • 文字描述TextArea(005 篇);
  • 方向二态(好评/踩) → Toggle(017 篇)。

多数场景是"Rating + TextArea"的组合拳:星级打分量、文字表细节。把这条刻进肌肉记忆,评价表单就不会做成"只有星星、没有心声"的半成品。


4. 完整可运行代码

下面是五个演示组件的核心片段(完整工程见同目录 ohos/)。

4.1 入口与页面整合

EntryAbility.ets 走标准生命周期,onWindowStageCreateloadContent('pages/Index')Index.etsTabs 把五个演示分页,结构同 013 篇的容器写法,仅 tabBar 用文字区分五大演示:

Tabs({ barPosition: BarPosition.Start, index: this.currentIndex }) {
  TabContent() { BasicDemo() }.tabBar('基础评分')
  TabContent() { HalfStarDemo() }.tabBar('半星支持')
  TabContent() { ReviewDemo() }.tabBar('商品评价')
  TabContent() { HistoryDemo() }.tabBar('历史评分')
  TabContent() { StyleDemo() }.tabBar('样式定制')
}
.barMode(BarMode.Scrollable)
.width('100%')
.height('100%')

4.2 基础评分:BasicDemo.ets

第一个演示把"值 + 刻度"讲透,顺带验证 stars 切换:

@State rating: number = 3;
@State starCount: number = 5;

Rating({ rating: this.rating })
  .stars(this.starCount)
  .stepSize(1)
  .starColor('#FFB800')
  .secondaryColor('#E0E0E0')
  .width(200)
  .height(40)
  .onChange((value: number) => {
    this.rating = value;
  })

设计点:底部三个按钮在 5/7/10 星间切换,切换时同步重置 rating 到区间内合法值(如 10 星制给 6)——因为 rating 超出 stars 会被框架夹取,主动给合法初值更稳。stepSize = 1 只出整星,评分值域与 stars 完全一致:5 星制满分 5、10 星制满分 10,值域即业务语义。

4.3 半星支持:HalfStarDemo.ets

第二个演示把"评分精度"变成可见的对比——一个 Toggle 切换 stepSize

@State rating: number = 3.5;
@State halfStep: boolean = true;

Rating({ rating: this.rating })
  .stars(5)
  .stepSize(this.halfStep ? 0.5 : 1)
  .starColor('#FFB800')
  .secondaryColor('#E0E0E0')
  .width(220)
  .height(44)
  .onChange((value: number) => {
    this.rating = value;
  })

设计点:halfStep = true 时用户能打出 3.5 星,false 时只能 3 或 4。切换时同步把 rating 调到"新精度下合法"的值(3.5 → 4),避免出现"半星值 + 整星精度"的错位。半星的价值在于:"还行但不够好"有了安放处——3.5 星和 4 星的差距,正是"将就"与"满意"的分界线,这也是电商评价普遍开半星的核心理由。

4.4 商品评价:ReviewDemo.ets

第三个演示是本文的主菜——"评分 → 提交 → 锁定"的完整闭环:

@State rating: number = 0;
@State submitted: boolean = false;

private desc(): string {
  const r = this.rating;
  if (r <= 0) return '未评价';
  if (r < 1.5) return '很差';
  if (r < 2.5) return '一般';
  if (r < 3.5) return '好';
  if (r < 4.5) return '很好';
  return '极好';
}

Rating({ rating: this.rating, indicator: this.submitted })
  .stars(5)
  .stepSize(0.5)
  .starColor('#FFB800')
  .secondaryColor('#E0E0E0')
  .width(240)
  .height(48)
  .onChange((value: number) => {
    this.rating = value;
  })

if (!this.submitted) {
  Button('提交评分')
    .enabled(this.rating > 0)        // 未评分置灰
    .onClick(() => {
      this.submitted = true;
      promptAction.showToast({ message: `评分 ${this.rating.toFixed(1)} 星提交成功`, duration: 1500 });
    })
}

设计点有三:

  • 文字描述联动desc() 把 0~5 映射成"很差/一般/好/很好/极好",颜色再按档位变色(高分绿、中分蓝、低分红)——评分从"抽象的星"变成"看得懂的话";
  • 提交门槛rating = 0(未评)时提交按钮置灰,逼用户"至少打一分再提交",避免空评灌水;
  • 提交即锁定:点提交后 submitted = trueRatingindicator 同步翻真,评分区自动变只读;"重新评价"一键解锁重来。

这个演示把 Rating 的"输入面孔"与"展示面孔"无缝衔接:提交那一刻,用户刚打的分数就从"意愿"变成了"记录"indicator 就是那道门。

4.5 历史评分展示:HistoryDemo.ets

第四个演示是商品详情页的评分区——只读大分 + 商品列表均分:

private readonly avg: number = 4.7;

Rating({ rating: this.avg, indicator: true })
  .stars(5)
  .stepSize(0.1)          // 小数均分要配小 step,避免 4.8 被吸附成 5
  .starColor('#FFB800')
  .secondaryColor('#E0E0E0')
  .width(140)
  .height(26)

ForEach(RATING_LIST, (item: RatingItem) => {
  Row() {
    Text(item.name)
    Rating({ rating: item.rating, indicator: true })
      .stars(5)
      .stepSize(0.1)
      .width(110)
      .height(22)
    Text(`${item.rating.toFixed(1)}`)
    Text(`${item.count}`)
  }
}, (item: RatingItem) => item.name)

设计点有两个:

  • 大分 + 星 + 人数三件套:"4.7"大字、半亮星星、“基于 45620 条评价”,是电商评分区的标准配置——数字给结论、星星给直觉、人数给可信度;
  • stepSize = 0.1 保真展示:4.8 星、4.3 星这类小数均分,只有小步进才能精确点亮对应比例,这是"展示失真坑"的正解(6.2 详解)。

4.6 样式定制:StyleDemo.ets

第五个演示把三色体系与尺寸定制全部摆出来:

Rating({ rating: this.gold })
  .starColor('#FFB800').secondaryColor('#E0E0E0')
  .width(180).height(40)

Rating({ rating: this.rose })
  .starColor('#FF5C8A').secondaryColor('#F5D5E0')
  .width(150).height(30)

Rating({ rating: this.blue })
  .starColor('#4A90D9').secondaryColor('#E3E8F0')
  .starBackgroundColor('#F0F4FA')
  .width(150).height(30)

Rating({ rating: 4.5, indicator: true })
  .width(120).height(24)          // 只读小星星

设计点:经典金、玫粉、科技蓝三套配色 + 只读小星,演示"评分贴合品牌色与页面密度"的定制方式。starBackgroundColor 给星星加一层底色,适合浅色卡片上"星星太淡"的场景。

4.7 无障碍与评价防刷细节

容易被漏的两点:

  • 无障碍Rating 默认支持读屏,但读屏播报的是"评分 4 分",建议配合文字描述(如"很好")让视障用户获得完整语义;用 .accessibilityText() 自定义播报更佳;
  • 评价防刷:前端评分组件只负责"采集",防刷(一人一评、频控、风控)全部在服务端。前端可以做的只有"提交前本地校验"(未评分置灰)和"提交后锁定"(indicator 翻真)——把这两道做到,前端职责就圆满了。

5. 模拟器验证

本文所有示例在 DevEco Studio 模拟器(Phone API 12)验证通过。验证要点:

  1. 基础评分:5/7/10 星切换后值域同步变化,点击星星即时回显;
  2. 半星支持stepSize 切换后 3.5 星可选/不可选,数值显示正确;
  3. 商品评价:未评分提交按钮置灰;打分后描述文字随档位变色;提交后锁定只读、Toast 提示;重新评价可解锁;
  4. 历史评分:只读星星精确显示 4.8/4.6/4.7 等小数均分,不可点击;
  5. 样式定制:三套配色与大小尺寸正常渲染,只读小星不变形。

5.1 预期效果截图

在这里插入图片描述
在这里插入图片描述

5.2 模拟器与真机的差异

维度 模拟器表现 真机表现 是否需处理
点击评分 鼠标点击 手指点按 功能一致
拖动评分 鼠标拖拽 手指滑动 手感差异
星星渲染 一致 一致 无需
只读展示 一致 一致 无需
触控精度 鼠标更"点" 手指更"滑" 真机校准星间距

一句话:模拟器负责把"功能跑通、逻辑正确",真机负责把"手感校准、星距验收"。本文示例上真机功能应一致;手感类差异按上表逐项核对。


6. 调试与排错

6.1 点了星星值不变

按优先级排查:

  1. rating 没绑 @State:状态不回写、星星不亮;
  2. onChange 里没回写:事件只上报,必须 this.rating = value
  3. indicator 误开indicator = true 时星星只读,点不动是预期行为——检查是不是把展示面孔用在了输入场景。

一句话:值要进 @State,回调要回写,面孔要对,三件事齐了,星星才"活"。

6.2 均分显示失真:4.8 显示成 5 星全亮

这是"展示失真坑":stepSize 太大(默认 0.5 都不够),4.8 被吸附到 5.0,五颗星全亮。解法:只读展示的 stepSize 调小到 0.1,让小数均分精确点亮对应比例。展示均分时,stepSize 的职责从"输入精度"变成"显示保真度",别用默认值裸奔。

6.3 切换星星数后值越界

stars 从 5 切到 10,rating 若还是 8(旧值)没问题;但从 10 切回 5,rating = 8 就超了值域,框架夹取到 5——表现是"明明打了 8 分,显示却是 5 星"。解法:切换 stars 时同步重置 rating 到新值域内(4.2 的按钮就这么做)。

6.4 拖动评分跳变

  • 跳变stepSize = 1 时拖动跨星跳变是正常的(精度设计),不是 bug;
  • 值对不上onChange 里对 value 二次取整,或 rating 回写用了别的变量。回调参数就是吸附后的最终值,直接用,别加工。

6.5 半星切换后显示"半星残留"

stepSize 从 0.5 切到 1,rating = 3.5 这个半星值在新精度下不合法,显示可能停在 3.5。解法:切换精度的同时把 rating 吸附到新精度的合法值(4.3 的 3.5 → 4 就是标准姿势)。

6.6 评分区点击穿透

Rating 放在可点击卡片里(如"点卡片进详情"),星星的点击会被卡片吃掉或穿透。解法:星星区域用 .onClick 显式拦截(Rating 自带点击处理,通常不会穿透),若卡片有整块点击手势,把评分区提升层级或用空白 Blank 隔离。先把高频问题收成速查表:

点了星星值不变
rating 未进 @State / onChange 未回写 / indicator 误开
4.8 显示成 5 星
只读 stepSize 调小到 0.1,保真展示均分
切星星数后值越界
切换 stars 时同步重置 rating
半星残留
切 stepSize 时把 rating 吸附到新精度合法值
点击被卡片吃掉
检查外层手势,评分区提升层级或隔离

7. 总结与扩展

7.1 本文知识地图

Rating 核心能力收成一张图,便于回顾:

Rating 评分组件

值: rating 0~stars

刻度: stars + stepSize

面孔: indicator 输入/只读

事件: onChange 回数值

样式: 三色体系 + 尺寸

值域即满分, 越界被夹取

stepSize 定输入精度与显示保真

提交后 indicator 翻真 = 锁定

吸附后的最终值, 直接用

7.2 评分交互的设计规范

把本文散落的原则收成五条,作为写评分的检查清单:

  1. 默认 5 星 + 半星:0.5 步进是电商评价主流,"还行"有处安放;
  2. 只读配小 step:展示均分用 0.1,4.8 不显示成 5;
  3. 文字描述联动:星级旁边挂"很好/一般"档位词,抽象变具体;
  4. 提交即锁定indicator 翻真,评分区从输入变只读;
  5. 防刷在服务端:前端只管采集与锁定,别在前端做"真校验"。

7.3 三个真实踩坑复盘

  • 案例一:商品详情页 4.8 分显示五颗星全亮stepSize 用了默认值,4.8 被吸附成 5。改为 stepSize(0.1) 后精确显示四星半。
  • 案例二:切换 10 星制后评分"神秘归零"rating = 8 是合法的,但用户再点一次、组件把 8 当新值吸附——实际是切回 5 星制时 8 越界被夹取成 5,来回切几次就乱了。切换时重置 rating 后稳定。
  • 案例三:提交后还能拖动评分。只在 onClick 里拦了提交按钮,忘了 Rating 本身还可点。indicator 翻真后彻底锁死,问题消失。

这类问题共性:都不是组件坏了,而是"有没有把 Rating 当’一把带刻度的尺子’去设计"——值域、精度、面孔、反馈四件事照顾到,问题在写代码时就能消灭。

7.4 后续可沿三条线深入

  1. 与 TextArea 组合:评价表单"星级 + 文字"双件套,评分联动星级描述(005 篇);
  2. 与统计结合:评分分布条(5 星占 62% 的横向条形图)与均分加权计算,做详情页评分区;
  3. 与状态管理结合rating 提升到视图模型,评价列表与详情页共享"我的评分"(051–075 篇)。

给一条量化的学习路线,按天推进即可:

2026-08-15 2026-08-16 2026-08-17 2026-08-18 2026-08-19 2026-08-20 2026-08-21 2026-08-22 2026-08-23 2026-08-24 2026-08-25 2026-08-26 2026-08-27 2026-08-28 2026-08-29 值与刻度模型 stepSize 精度与吸附 商品评价闭环 历史评分展示 样式定制与无障碍 评分统计与状态管理 基础 进阶 深化 Rating 进阶学习路线

回到开头:Rating 是一排有刻度的星星——rating 是当前值、stars 是满分、stepSize 是精度、indicator 是面孔。本文从这把"星星尺子"的心智模型出发,逐层拆了值、刻度、面孔、事件、样式五环,又用五个演示把它落到基础评分、半星、评价闭环、历史展示、样式五个真实场景。写 Rating 时若能始终记住"值进 @State、回调即最终值、展示配小 step、提交翻 indicator",那么无论商品评价、服务打分还是均分展示,都能点得准、点得美、点得稳。把这份理解带回项目,下一个"评分失准/显示失真"的工单,大概就能在写代码时消灭在萌芽里。

Rating 是 ArkUI 里最"轻"的组件之一:用户点五下就完成一次评价,可一旦它不亮、失真、锁不住,整个评价体系的信任就垮了。把本文五环吃透,你就能从容撑起从商品评价到评分统计的全部场景。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐