当前位置: 首页 > news >正文

HarmonyOS7 ArkUI 视频列表 - 封面卡片、播放量、关注按钮实战

文章目录

      • 前言
      • 从界面倒推代码
      • 交互入口在哪里
      • 代码里的重点
        • 片段 1:`toggleFollow(id: number) {`
        • 片段 2:`likesDisplay(count: number): string {`
      • 使用方式
      • 完整代码
      • 收个尾

前言

这篇不讲空概念,直接从页面代码拆。能复用的不是某个颜色值,而是状态、派生数据和布局之间的组织方式。
它的主线是视频列表,细节落在封面卡片、播放量、关注按钮。这些细节刚好能把页面状态、用户操作和组件刷新串起来。

从界面倒推代码

VideoFeedPage不是一个只展示静态内容的页面。它会根据用户点击、输入、切换或计时来改变界面,所以阅读代码时可以先抓三条线:

观察点在这个案例里的表现

| 页面主题 |视频列表|
| 主要文案 |教程,3天前,设计,1天前,创意,5天前|
| 常用组件 |Column,ForEach,Row,Scroll,Stack,Text|
| 适合练习 | 状态驱动 UI、条件样式、列表渲染、事件回调 |

交互入口在哪里

ArkUI 的页面刷新依赖状态变化。下面这些@State字段就是页面的“开关”和“数据源”,不用手动找 DOM,也不用自己通知某个控件刷新。

状态字段类型我会怎么理解它
videosVideoItem_75fu[]列表数据源,通常会被ForEach消费
activeCategorystring当前选中项,决定高亮和内容切换
searchTextstring用户输入值,参与计算或提交

一个经验:先把@State看完,再看build(),页面逻辑会清楚很多。否则很容易被一长串布局代码带偏。

代码里的重点

片段 1:toggleFollow(id: number) {

这段代码承担的是页面里的“判断”或“动作”,把它从布局里抽出来后,build()会清爽很多。后面要加新条件,也不会到处翻 UI 代码。

toggleFollow(id:number){this.videos=this.videos.map(v=>{if(v.id===id){v.isFollowed=!v.isFollowedreturnv}returnv})}

片段 2:likesDisplay(count: number): string {

这段代码承担的是页面里的“判断”或“动作”,把它从布局里抽出来后,build()会清爽很多。后面要加新条件,也不会到处翻 UI 代码。

likesDisplay(count:number):string{returncount>=10000?(count/10000).toFixed(1)+'万':count+''}

使用方式

把下面代码放进 ArkTS 页面文件中即可运行。用于正式项目时,我会继续把数据模型、卡片 Builder 和页面事件拆出去,页面文件只负责组合。

建议练习顺序:先改状态字段 -> 再改交互事件 -> 最后调整 UI 样式 检查重点:点击是否刷新、列表 key 是否稳定、条件样式是否集中管理
这份代码可以继续扩展的方向
  • 把模拟数据替换成接口数据
  • 抽出复用卡片组件
  • 增加空状态和异常状态
  • 补充深色模式或主题色适配
  • 对输入类场景增加校验提示

完整代码

// VideoFeedPage - 视频列表(封面卡片、播放量、关注按钮)interfaceVideoItem_75fu{id:numbertitle:stringauthor:stringavatar:stringcoverColor:ResourceColor coverEmoji:stringviews:stringlikes:numberduration:stringcategory:stringisFollowed:booleanpublishTime:string}interfaceCategoryTab_i98l{key:stringlabel:string}@Entry@Componentstruct VideoFeedPage{@Statevideos:VideoItem_75fu[]=[{id:1,title:'HarmonyOS ArkTS 零基础入门教程 | 手把手教你开发第一个鸿蒙应用',author:'鸿蒙技术派',avatar:'🦁',coverColor:'#1E3A5F',coverEmoji:'📱',views:'18.6万',likes:3420,duration:'23:45',category:'教程',isFollowed:false,publishTime:'3天前'},{id:2,title:'UI设计神技 | 10个让界面瞬间高级的小技巧,99%的人不知道',author:'UI大魔王',avatar:'🎨',coverColor:'#3D1A78',coverEmoji:'✨',views:'45.2万',likes:8900,duration:'12:30',category:'设计',isFollowed:true,publishTime:'1天前'},{id:3,title:'用代码画出星空 | p5.js 粒子系统实战演示',author:'代码艺术家',avatar:'🌟',coverColor:'#0A1628',coverEmoji:'🌌',views:'7.3万',likes:1580,duration:'18:22',category:'创意',isFollowed:false,publishTime:'5天前'},{id:4,title:'2024 最值得学的前端框架大盘点,别再迷茫了!',author:'前端老炮儿',avatar:'💻',coverColor:'#1A3A1A',coverEmoji:'🚀',views:'32.1万',likes:6200,duration:'15:10',category:'教程',isFollowed:true,publishTime:'2天前'},{id:5,title:'从0到1搭建完整的后台管理系统 | Vue3 + TypeScript 实战',author:'全栈工程师小明',avatar:'⚡',coverColor:'#3A1A1A',coverEmoji:'🛠️',views:'9.8万',likes:2100,duration:'45:00',category:'实战',isFollowed:false,publishTime:'1周前'},{id:6,title:'设计师眼中的好代码 | 前端与UI如何高效协作',author:'协作达人',avatar:'🤝',coverColor:'#1A2A3A',coverEmoji:'💡',views:'5.6万',likes:890,duration:'20:15',category:'经验',isFollowed:false,publishTime:'4天前'}]@StateactiveCategory:string='推荐'@StatesearchText:string=''privatecategories:CategoryTab_i98l[]=[{key:'推荐',label:'🔥 推荐'},{key:'教程',label:'📚 教程'},{key:'设计',label:'🎨 设计'},{key:'实战',label:'⚡ 实战'},{key:'创意',label:'✨ 创意'}]toggleFollow(id:number){this.videos=this.videos.map(v=>{if(v.id===id){v.isFollowed=!v.isFollowedreturnv}returnv})}likesDisplay(count:number):string{returncount>=10000?(count/10000).toFixed(1)+'万':count+''}getfilteredVideos():VideoItem_75fu[]{if(this.activeCategory==='推荐')returnthis.videosreturnthis.videos.filter(v=>v.category===this.activeCategory)}@BuildervideoCard(video:VideoItem_75fu){Column({space:0}){// 视频封面Stack({alignContent:Alignment.Bottom}){// 封面背景Column(){Text(video.coverEmoji).fontSize(60)}.width('100%').height(180).backgroundColor(video.coverColor).justifyContent(FlexAlign.Center).borderRadius({topLeft:12,topRight:12})// 时长标签Row(){Blank()Text(video.duration).fontSize(12).fontColor('#FFFFFF').padding({left:8,right:8,top:3,bottom:3}).backgroundColor('#000000AA').borderRadius(6)}.width('100%').padding({right:10,bottom:10})// 播放按钮(圆形半透明)Circle({width:50,height:50}).fill('#00000060').position({x:'50%',y:'50%'}).translate({x:-25,y:-25-10})Text('▶').fontSize(18).fontColor('#FFFFFF').position({x:'50%',y:'50%'}).translate({x:-8,y:-8-10})}.width('100%')// 视频信息Row({space:10}){// 作者头像Text(video.avatar).fontSize(24).width(40).height(40).textAlign(TextAlign.Center).backgroundColor('#F3F4F6').borderRadius(20)Column({space:4}){Text(video.title).fontSize(14).fontColor('#111827').maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}).lineHeight(20)Row({space:6}){Text(video.author).fontSize(12).fontColor('#6B7280')Text('·').fontSize(12).fontColor('#D1D5DB')Text(video.views+'次播放').fontSize(12).fontColor('#9CA3AF')Text('·').fontSize(12).fontColor('#D1D5DB')Text(video.publishTime).fontSize(12).fontColor('#9CA3AF')}}.layoutWeight(1).alignItems(HorizontalAlign.Start)}.width('100%').padding({left:12,right:12,top:10,bottom:6})// 底部互动栏Row({space:0}){Row({space:6}){Text('👍').fontSize(14)Text(this.likesDisplay(video.likes)).fontSize(13).fontColor('#6B7280')}.layoutWeight(1)Row({space:6}){Text('💬').fontSize(14)Text('评论').fontSize(13).fontColor('#6B7280')}.layoutWeight(1)Row({space:6}){Text('↗️').fontSize(14)Text('分享').fontSize(13).fontColor('#6B7280')}.layoutWeight(1)// 关注按钮Text(video.isFollowed?'✓ 已关注':'+ 关注').fontSize(13).fontColor(video.isFollowed?'#6B7280':'#FFFFFF').padding({left:14,right:14,top:6,bottom:6}).backgroundColor(video.isFollowed?'#F3F4F6':'#3B82F6').borderRadius(16).onClick(()=>this.toggleFollow(video.id))}.width('100%').padding({left:12,right:12,top:4,bottom:12})}.width('100%').backgroundColor('#FFFFFF').borderRadius(12).shadow({radius:6,color:'#00000010',offsetX:0,offsetY:2}).clip(true)}build(){Column(){// 顶部搜索栏Row({space:10}){Row({space:8}){Text('🔍').fontSize(16).fontColor('#9CA3AF')Text('搜索视频、创作者...').fontSize(14).fontColor('#9CA3AF')Blank()}.layoutWeight(1).height(40).padding({left:14,right:14}).backgroundColor('#F3F4F6').borderRadius(20)Text('🔔').fontSize(22)Text('👤').fontSize(22)}.width('100%').padding({left:16,right:16,top:50,bottom:12}).backgroundColor('#FFFFFF')// 分类 TabScroll(){Row({space:8}){ForEach(this.categories,(cat:CategoryTab_i98l)=>{Text(cat.label).fontSize(14).fontColor(this.activeCategory===cat.key?'#FFFFFF':'#374151').padding({left:16,right:16,top:8,bottom:8}).backgroundColor(this.activeCategory===cat.key?'#3B82F6':'#F3F4F6').borderRadius(20).onClick(()=>{this.activeCategory=cat.key})})}.padding({left:16,right:16,bottom:10,top:4})}.scrollable(ScrollDirection.Horizontal).backgroundColor('#FFFFFF').border({width:{bottom:0.5},color:'#F3F4F6'})// 视频列表Scroll(){Column({space:14}){ForEach(this.filteredVideos,(video:VideoItem_75fu)=>{this.videoCard(video)})}.padding({left:16,right:16,top:14,bottom:30})}.layoutWeight(1).backgroundColor('#F9FAFB')}.width('100%').height('100%').backgroundColor('#F9FAFB')}}

收个尾

这个案例可以当成一个小模板:先把页面会变的东西放进状态,再用函数或 Builder 处理重复逻辑,最后让布局只关心展示。写 HarmonyOS7 页面时,这个顺序通常比一上来堆 UI 更稳。

http://www.cnnetsun.cn/news/3679299.html

相关文章:

  • PyPI供应链攻击深度解析:从LiteLLM恶意包事件看开源依赖安全
  • 解决ssh的rviz显示问题
  • 基于HarmonyOS API 24 React Native跨平台鸿蒙开发实战系列:输入表单如何适配任何机型,总是占据页面下部分
  • AI辅助学术写作:人机协同的认知革命与实践指南
  • KVM主题:XML配置热更新与版本管理实践
  • 向量数据库实战:选型、调优与落地~系列文章19:向量数据库 + RAG 融合实战:构建企业级知识库的完整链路
  • 向量数据库实战:选型、调优与落地~系列文章20:向量数据库在推荐系统中的应用:从协同过滤到向量召回
  • TMS320C6421开发全解析:从命名规则到工具链与实战避坑指南
  • LangChain结构化输出:Pydantic与JSON解析器实战
  • uv:快得像火箭,顺便把“安装依赖”藏起来了
  • FSDrive框架:时空思维链与视觉推理的自动驾驶决策
  • TVA数字小脑:具身智能的物理交互革命(7)
  • MSO算法在柔性作业车间调度中的Matlab实现与优化
  • HsMod终极指南:32倍速炉石传说插件,200+皮肤定制与自动化功能完全解析
  • TVA数字小脑:具身智能产业化落地的关键支撑(9)
  • TVA数字小脑:具身智能产业化落地的关键支撑(10)
  • 定点DSP上IIR滤波器优化:规范型结构防溢出与高效实现
  • Python作业实战:函数与数据结构进阶指南
  • 云原生12要素应用开发实践指南
  • Java后端面试7天冲刺:系统化复习八股文与场景题实战
  • GPT-4o企业级成本优化实战:从Prompt设计到架构部署
  • 功率谱估计算法从零详解(纯C#原生实现、无第三方库、超全理论+源码)
  • 英雄联盟智能助手Seraphine:告别繁琐查询,3分钟掌握全队数据
  • MiniMax Agent:全栈式AI智能代理的技术解析与应用
  • MySQL SQL执行全链路解析:从Parser到Executor的完整生命周期
  • AI动态调整销售目标的技术实现与实战经验
  • TI 64位定时器看门狗配置详解:从原理到防误触发实战
  • 688号文多用户绿电直连全流程拆解|全网独家复现源荷储能收益仿真 双阶段入市模式、四维交易能力、多方风险收益分配助力园区零碳落地、算力负荷稳供、绿碳资产增值
  • 英雄联盟智能助手Seraphine:如何用免费开源工具提升你的游戏胜率
  • TMS320C6474 DSP电源设计实战:CVDD、Bulk电容与SmartReflex详解