
前言在 HarmonyOS NEXT 应用开发中列表是最高频的 UI 模式之一。无论是社交动态流、电商商品展示还是新闻资讯聚合都离不开一个高性能、交互丰富的列表组件。本文将以一个完整的热点新闻聚合页面为例深入讲解使用 ArkTS 语言在 HarmonyOS 上构建新闻类应用的核心技术点涵盖数据模型设计、多分类标签、热度排行、拖拽排序、视觉效果实现等实用技巧。最终效果是一个功能完善的新闻列表页面——支持 6 大新闻分类、实时热度排行展示、长按拖拽自定义排序以及优雅的渐变视觉设计。1. 数据模型设计数据模型是应用的骨架。在设计新闻列表的数据结构时我们需要思考一条新闻需要承载哪些信息interfaceNewsItem{id:number;// 唯一标识title:string;// 新闻标题source:string;// 来源媒体category:科技|财经|体育|娱乐|国际|社会;// 分类hotScore:number;// 热度值summary:string;// 内容摘要time:string;// 发布时间coverColor:string;// 卡片左侧标识色}设计考量1. 联合类型约束分类category:科技|财经|体育|娱乐|国际|社会使用 TypeScript 的联合类型Union Type而非普通string可以在编译期就约束分类值的合法性。如果后续需要新增分类如健康、“教育”只需在联合类型中追加即可IDE 会提示所有引用位置需要同步更新避免了运行时才发现拼写错误的尴尬。2. 热度值使用原始数值hotScore存储原始数值如 9865000而非格式化后的字符串。这样做的好处是排序运算直接使用数值比较性能更高在不同展示场景下可以灵活格式化万/千万/亿便于后续对接真实数据 API3. 卡片颜色内嵌数据coverColor字段让每条新闻拥有独立的左侧边框颜色视觉上形成差异化。颜色既可以根据分类自动分配也可以从服务端下发实现个性化和品牌化。分类样式映射为了让每个新闻分类拥有独特的视觉标签我们设计了CategoryStyle接口并配合getCategoryStyle方法interfaceCategoryStyle{fontColor:string;bgColor:string;text:string;}getCategoryStyle(category:string):CategoryStyle{switch(category){case科技:return{fontColor:#1565C0,bgColor:#E3F2FD,text:科技};case财经:return{fontColor:#E65100,bgColor:#FFF3E0,text:财经};case体育:return{fontColor:#2E7D32,bgColor:#E8F5E9,text:体育};case娱乐:return{fontColor:#AD1457,bgColor:#FCE4EC,text:娱乐};case国际:return{fontColor:#6A1B9A,bgColor:#F3E5F5,text:国际};default:return{fontColor:#4E342E,bgColor:#EFEBE9,text:社会};}}6 个分类各自拥有独立的配色方案符合视觉语义化——蓝调科技、橙金财经、翠绿体育、粉红娱乐、紫韵国际、棕灰社会。2. 热度展示系统热度是新闻内容的核心指标之一。我们设计了一套简洁而有层次的热度展示方案。热度数值格式化原始热度值如9865000对用户不够友好需要做人性化格式化formatHotScore(score:number):string{if(score10000000){return(score/10000000).toFixed(1)千万;}if(score10000){return(score/10000).toFixed(0)万;}returnscore.toString();}千万级≥1000万显示为9.9千万保留 1 位小数万级≥1万显示为875万取整小于 1 万直接显示原始数值热度图标分档为了让热度感知更加直观使用 Emoji 图标按档位区分getHotIcon(score:number):string{if(score9000000)return;// 爆款if(score7000000)return;// 热门if(score5000000)return;// 上升return;// 普通}热度档位阈值图标含义爆款级≥ 900万现象级传播热门级≥ 700万广泛关注上升级≥ 500万热度攀升普通级 500万常规新闻这种分层设计让用户一眼就能判断新闻的热烈程度比单纯的数字更有感染力。3. 新闻卡片设计新闻卡片是本页面最核心的 UI 单元承载了标题、摘要、分类、来源、时间、热度六个维度的信息。Builder 装饰器在 ArkTS 中使用Builder装饰器定义可复用的 UI 构建函数BuilderNewsCard(item:NewsItem):void{Column(){// 标题Text(item.title).fontSize(17).fontColor(#1A1A1A).fontWeight(FontWeight.Bold).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}).width(100%)// 摘要Text(item.summary).fontSize(13).fontColor(#888888).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}).width(100%).margin({top:8})// 底部信息栏Row(){Text(categoryStyle.text)// 分类标签.fontSize(11).fontColor(categoryStyle.fontColor).backgroundColor(categoryStyle.bgColor).borderRadius(3).padding({left:6,right:6,top:2,bottom:2})Text(item.source)// 来源.fontSize(12).fontColor(#BBBBBB).margin({left:10})Text(item.time)// 时间.fontSize(12).fontColor(#BBBBBB).margin({left:6})Blank()// 弹性填充Text(getHotIcon(item.hotScore)formatHotScore(item.hotScore)热度).fontSize(12).fontColor(#FF6B6B).fontWeight(FontWeight.Medium)}.width(100%).margin({top:10})}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(12).border({width:{left:4},color:item.coverColor}).shadow({radius:4,color:rgba(0,0,0,0.06),offsetY:2})}视觉层次解析整个卡片的信息架构分为三个视觉层级第一层标题17px加粗深黑吸引用户第一注意力阐述新闻核心内容。maxLines(2)限制两行溢出保持卡片高度一致。第二层摘要13px灰色补充标题外的关键信息帮助用户快速判断是否感兴趣。同样限制两行。第三层元信息11-12px彩色/浅灰分类标签用品牌色 浅底色强化识别来源、时间用浅灰色弱化存在感热度值用红色 图标吸引对热度的关注。左侧彩色边框.border({width:{left:4},color:item.coverColor})这是新闻卡片最具辨识度的视觉特征。每条新闻有独立的左边框颜色当用户快速滑动列表时不同颜色的边框形成视觉锚点便于定位。10 条模拟数据使用了 10 种不同颜色实际项目中可以从服务端配置。4. 排名序号系统在新闻卡片左侧展示排名序号是热度榜单的经典设计模式if(!this.isEditMode){Text(${index1}).fontSize(28).fontColor(index3?#FF6B6B:#CCCCCC).fontWeight(index3?FontWeight.Bold:FontWeight.Regular).width(40).textAlign(TextAlign.Center).margin({right:4})}设计细节前三名特殊高亮使用条件表达式index 3 ? #FF6B6B : #CCCCCC让前三名用醒目的红色显示其余用浅灰色。这与大多数排行榜的金银铜逻辑一致——前三名是用户重点关注对象。编辑模式隐藏if (!this.isEditMode)确保在拖拽排序模式下隐藏序号因为排序过程中序号的变化会造成视觉干扰。排序完成退出编辑后序号自动刷新。固定宽度居中对齐width(40)textAlign(TextAlign.Center)保证序号列宽度统一不会因数字位数不同而错位。5. 拖拽排序实现拖拽排序是 HarmonyOS List 组件内置的强大能力。借助editMode和onItemMove两个 API只需少量代码即可实现完整的拖拽排序交互。状态管理StateisEditMode:booleanfalse;使用State装饰器将编辑模式状态声明为响应式变量。当isEditMode变化时UI 自动刷新——提示文字切换、拖拽把手显示/隐藏、完成按钮出现/消失。进入编辑模式.gesture(LongPressGesture({duration:400}).onAction((){this.isEditModetrue;}))长按手势绑定在每个ListItem上触发时长设为 400ms避免与普通点击冲突。长按后isEditMode置为true整个列表进入可拖拽状态。启用拖拽List({space:10}){ForEach(this.items,(item:NewsItem,index:number){ListItem(){/* ... */}},(item:NewsItem)item.id.toString())}.editMode(this.isEditMode).onItemMove((from:number,to:number){constmoveItemthis.items.splice(from,1)[0];this.items.splice(to,0,moveItem);this.saveOrder();returntrue;})关键 APIeditMode(true)激活列表编辑模式ListItem 自动支持拖拽手势onItemMove拖拽完成后的回调提供源索引from和目标索引to核心的数组重排逻辑只有三行constmoveItemthis.items.splice(from,1)[0];// 从源位置取出this.items.splice(to,0,moveItem);// 插入到目标位置this.saveOrder();// 持久化新顺序ForEach 的 key 函数(item:NewsItem)item.id.toString()这是拖拽排序中极易被忽略但至关重要的细节。ForEach的第三个参数是 key 生成函数它决定了框架如何追踪每个列表项的身份。拖拽排序会导致数组元素的索引发生变化如果使用默认的索引追踪ForEach可能无法正确更新 UI。通过指定item.id.toString()作为唯一标识框架能够精确识别每个列表项的移动轨迹确保拖拽动画流畅且 UI 正确刷新。拖拽把手当进入编辑模式后每行右侧会出现一个三横线拖拽把手向用户传达此地可拖拽的信号if(this.isEditMode){Column(){Row().width(16).height(2.5).backgroundColor(#CCCCCC).borderRadius(1)Row().width(16).height(2.5).backgroundColor(#CCCCCC).borderRadius(1).margin({top:4})Row().width(16).height(2.5).backgroundColor(#CCCCCC).borderRadius(1).margin({top:4})}.width(36).height(36).justifyContent(FlexAlign.Center).backgroundColor(rgba(0,0,0,0.03)).borderRadius(8).margin({left:8})}不直接使用图片素材——用三根纯色Row绘制保持像素级精度且零额外资源开销。配合浅灰底色和圆角视觉上干净内敛。退出编辑模式顶部和底部分别提供一个完成按钮确保用户无论在列表的哪个位置都能方便退出// 顶部按钮Row 右侧if(this.isEditMode){Button(){Text(完成)}.backgroundColor(rgba(255,255,255,0.9)).onClick((){this.isEditModefalse;})}// 底部悬浮按钮Button(完成排序).type(ButtonType.Capsule).backgroundColor(rgba(255,255,255,0.95)).onClick((){this.isEditModefalse;})6. 主题视觉设计背景渐变使用linearGradient为整个页面铺设深蓝渐变背景营造专业、可信赖的新闻阅读氛围.linearGradient({direction:GradientDirection.Top,colors:[[#1A237E,0.0],[#283593,0.5],[#3949AB,1.0]]})三个色阶从顶部到底部由深到浅过渡与白色新闻卡片形成鲜明对比。选择深蓝而非纯黑是因为蓝调天然具有信息、知识、权威的心理暗示适合新闻类产品。安全区域适配.expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])将渐变背景扩展到系统状态栏和底部导航栏区域消除上下边缘的割裂感实现沉浸式全屏体验。这在 HarmonyOS 全面屏设备上尤为重要。卡片微阴影.shadow({radius:4,color:rgba(0,0,0,0.06),offsetY:2})轻微向下的阴影让白色卡片从渐变背景中浮起一层建立清晰的 Z 轴层级关系。rgba(0,0,0,0.06)的 6% 透明度度恰到好处——看得见层次又不喧宾夺主。7. 模拟数据策略在真实 API 接入之前页面内置了 10 条覆盖 6 大分类的模拟新闻数据确保开发阶段即可完整验证所有 UI 状态Stateitems:NewsItem[][{id:1,title:华为发布鸿蒙OS Next开发者预览版全面拥抱AI原生体验,source:科技日报,category:科技,hotScore:9865000,time:2小时前,summary:华为在HDC大会上正式发布...,coverColor:#FF6B6B},// ... 共 10 条];模拟数据遵循以下原则分类全覆盖6 个分类均有代表验证所有标签配色热度分层覆盖爆款900万、热门700万、上升500万、普通四档时间自然分布从 1 小时到 10 小时前不等接近真实时间线标题长度多样有长标题20字和短标题验证文字截断逻辑颜色唯一性10 条新闻各有独立 coverColor验证左边框视觉差异8. 完整组件架构用一张图总结HotNews组件的整体架构HotNews (Entry Component) │ ├─ 数据层 │ ├─ items: NewsItem[] // 新闻数据源 │ └─ isEditMode: boolean // 编辑模式状态 │ ├─ 工具方法 │ ├─ formatHotScore() // 热度值格式化 │ ├─ getHotIcon() // 热度图标映射 │ ├─ getCategoryStyle() // 分类样式映射 │ └─ saveOrder() // 排序持久化 │ ├─ UI Builder │ └─ NewsCard(item) // 新闻卡片组件 │ └─ build() ├─ 顶部标题栏 编辑按钮 ├─ 模式提示文字动态切换 ├─ List空间10editMode onItemMove │ └─ ListItem × N │ ├─ 排名序号条件显示 │ ├─ NewsCard │ └─ 拖拽把手条件显示 └─ 完成排序按钮条件显示9. 扩展方向当前实现是一个功能完整的 MVP 版本以下是几个可行的扩展方向9.1 接入真实 API将State items的初始化从硬编码改为网络请求asyncaboutToAppear(){try{constrespawaithttp.createHttp().request(https://api.example.com/news/hot);this.itemsJSON.parse(resp.resultasstring).data;}catch(err){console.error(获取新闻失败,JSON.stringify(err));}}9.2 下拉刷新和加载更多利用 HarmonyOS 的Refresh组件包裹List实现下拉刷新和上拉加载更多构建完整的 Feed 流体验。9.3 排序持久化当前saveOrder()仅打印日志。可以通过 Preferences 首选项或 SQLite 关系型数据库持久化用户的排序结果下次打开应用时恢复。9.4 新闻详情页为每条新闻添加点击事件通过router.pushUrl()跳转到新闻详情页展示完整内容。可以配合NavPathStack实现更优雅的路由管理。9.5 深色模式适配使用$r(sys.color.xxx)系统资源引用替代硬编码色值让应用自动跟随系统深色/浅色模式切换提升用户体验一致性。9.6 搜索与筛选在顶部标题栏下方添加搜索框和分类筛选标签支持按关键词搜索新闻和按分类过滤列表。10. 总结本文以一个完整的热点新闻聚合页面为例系统地讲解了 HarmonyOS ArkTS 开发中涉及的核心技术技术点实现方式数据模型定义TypeScriptinterface 联合类型分类标签系统CategoryStyle接口 枚举映射热度可视化数值格式化 Emoji 图标分档复杂卡片布局BuilderColumn/Row组合排名序号ForEachindex 前三名高亮拖拽排序List.editMode()onItemMove视觉设计linearGradientshadowborder状态管理State 条件渲染从数据模型到 UI 渲染从状态管理到交互细节这套技术方案可以直接复用到各类列表场景——新闻资讯、社交媒体动态、电商商品流、任务管理、音乐歌单等。HarmonyOS 的 ArkUI 框架提供了声明式 UI 的便利性配合 ArkTS 的静态类型检查让开发者可以用更少的代码、更早地发现问题构建更健壮的应用。本文基于 HarmonyOS NEXT API 24 编写示例代码完整可运行。项目使用 kit.CoreSpeechKit、kit.AbilityKit、kit.ArkUI 等系统 Kit。