)
项目背景在日常开发中影视类应用是常见的练习项目涉及列表渲染、状态管理、多Tab切换、数据持久化等核心知识点。本文将通过HarmonyOS ArkTS实现一个功能完整的电影追剧与观影记录应用涵盖从数据结构设计到完整页面布局的全流程并提供可直接运行的完整源码。技术栈HarmonyOS SDKAPI 24 ArkTS DevEco Studio适用读者具备 ArkTS 基础希望提升实战能力的开发者项目效果本文使用 HarmonyOS 和 ArkTS 实现一个电影追剧与观影记录应用。功能完整UI 精美深蓝影院主题交互流畅采用卡片式布局和渐变色设计。项目使用 DevEco Studio 开发适配 API 24 及以上版本。运行效果功能介绍✅ 电影/电视剧分类浏览✅ 正在热映✅ 观影记录✅ 想看/看过/在看标记✅ 五星评分✅ 电影详情和简介✅ 片单管理✅ 观影统计✅ 电影搜索✅ 演员信息✅ 上映提醒✅ 短评记录✅ 观影时长统计✅ 电影推荐✅ 海报墙定义数据结构首先定义核心数据模型Movie这是整个应用的数据基石。设计时需要兼顾功能需求与 ArkTS 的状态管理特性——建议使用interface而非class以充分利用State和Observed的响应式能力。interfaceMovie{id:number;title:string;poster:string;rating:number;year:number;genre:string[];description:string;status:want|watching|watched;myRating?:number;}字段说明id唯一标识用于列表渲染的keystatus观影状态使用联合类型限制取值提高类型安全性myRating?用户自己的评分可选字段配合条件渲染显示初始化页面状态使用State装饰器管理页面响应式数据。这里初始化了两条示例数据用于展示效果实际项目中可从云端 API 或本地数据库加载。Stateprivatemovies:Movie[][{id:1,title:流浪地球2,poster:,rating:8.3,year:2023,genre:[科幻,灾难],description:太阳即将毁灭人类在地球表面建造出巨大的推进器带着地球一起寻找新家园。,status:watched,myRating:9},{id:2,title:满江红,poster:,rating:7.0,year:2023,genre:[悬疑,喜剧],description:南宋绍兴年间岳飞死后四年秦桧率领朝廷使团前往山西与金国和谈。,status:want},];StateprivatecurrentTab:number0;核心功能方法以下是实现业务逻辑的核心方法。这里展示完整的增删改和状态切换逻辑每个方法都直接操作State数组ArkTS 会自动触发 UI 更新。// 添加电影记录privateaddMovie(movie:Movie):void{// 生成新 ID取当前最大 ID 1constmaxIdthis.movies.length0?Math.max(...this.movies.map(mm.id)):0;this.movies[...this.movies,{...movie,id:maxId1}];}// 切换观影状态想看 → 在看 → 看过privatetoggleStatus(id:number):void{this.moviesthis.movies.map(movie{if(movie.id!id)returnmovie;constnextStatus:Recordstring,Movie[status]{want:watching,watching:watched,watched:want};return{...movie,status:nextStatus[movie.status]};});}// 删除电影记录privatedeleteMovie(id:number):void{this.moviesthis.movies.filter(moviemovie.id!id);}// 更新用户评分privateupdateRating(id:number,rating:number):void{this.moviesthis.movies.map(moviemovie.idid?{...movie,myRating:rating}:movie);}最佳实践提示操作State数组时始终创建新数组使用map、filter、展开运算符等而不是 push/splice 等原地修改。这样 ArkTS 的依赖追踪才能正确检测到变化并触发 UI 重绘。Builder 可复用组件使用Builder抽取可复用的电影卡片组件减少重复代码提升可维护性。这里展示了完整的卡片布局包括海报、信息、状态标签和操作按钮。BuilderItemCard(item:Movie){Column(){// 海报区域Text(item.poster).fontSize(50).width(100%).height(160).textAlign(TextAlign.Center).backgroundColor(#312E81).borderRadius(8)// 电影信息Column({space:4}){Text(item.title).fontSize(14).fontColor(Color.White).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})Row({space:4}){Text(⭐).fontSize(10)Text(${item.rating}).fontSize(12).fontColor(#FBBF24)Blank()Text(item.statuswatched?✅:item.statuswatching?:).fontSize(14)}.width(100%)}.padding({left:6,right:6,bottom:8})}.backgroundColor(#1E293B).borderRadius(12).shadow({radius:4,color:#00000040,offsetX:0,offsetY:2}).onClick((){// 点击卡片可触发详情跳转this.toggleStatus(item.id);})}完整 build() 页面布局将所有组件组合成完整页面。布局结构为顶部导航栏 → 搜索栏 → Tab 切换栏 → 内容区使用Tabs组件。build(){Column(){// 顶部导航栏Row(){Text(观影记录).fontSize(24).fontWeight(FontWeight.Bold).fontColor(Color.White)Blank()Row({space:16}){Text().fontSize(22).fontColor(Color.White)Text().fontSize(22).fontColor(Color.White)}}.width(100%).padding({left:20,right:20,top:12,bottom:12}).backgroundColor(#1E3A8A)// 搜索栏视觉占位可扩展实现搜索功能Row(){Text( 搜索电影、电视剧、演员...).fontSize(14).fontColor(Color.Gray).layoutWeight(1)}.width(100%).height(40).backgroundColor(#334155).borderRadius(8).margin({left:16,right:16,top:8}).padding({left:12})// Tab 切换区域Tabs({barPosition:BarPosition.Start}){TabContent(){Scroll(){Grid(){ForEach(this.movies,(movie:Movie){GridItem(){this.ItemCard(movie)}},(movie:Movie)movie.id.toString())}.columnsTemplate(1fr 1fr 1fr).columnsGap(10).rowsGap(16).width(100%).padding(16)}.scrollBar(BarState.Off)}.tabBar(发现)TabContent(){Column().width(100%).height(100%).backgroundColor(#1E293B).justifyContent(FlexAlign.Center)Text( 创建你的专属片单).fontSize(16).fontColor(#94A3B8)}.tabBar(片单)TabContent(){Column().width(100%).height(100%).backgroundColor(#1E293B).justifyContent(FlexAlign.Center)Text( 我的观影记录).fontSize(16).fontColor(#94A3B8)}.tabBar(我的)}.width(100%).layoutWeight(1).barHeight(50).backgroundColor(#1E3A8A)}.width(100%).height(100%).backgroundColor(#0F172A)}关键设计点ForEach使用movie.id.toString()作为 key确保列表更新高效使用Blank()实现弹性空白布局深色主题配色#0F172A→#1E3A8A→#312E81层次递进页面设计说明设计系统主色#1E3A8A深海蓝用于顶部导航和 Tab 栏辅色#60A5FA浅蓝用于强调和高亮背景各层级分别采用#0F172A/#1E293B/#334155构建清晰视觉层次卡片圆角 12px搭配柔和阴影营造浮层效果字体标题 24px Bold正文 13-14px保持阅读舒适度SDK 配置确保build-profile.json5中的 SDK 版本配置正确{ apiType: stageMode, buildOption: {}, targets: [ { name: default, runtimeOS: HarmonyOS } ] }compileSdkVersionAPI 24compatibleSdkVersion“6.1.1(24)”运行项目使用 DevEco Studio 创建新的 ArkTS 项目API 24将上述代码复制到entry/src/main/ets/pages/Index.ets确保entry/src/main/ets/entryability/EntryAbility.ets中路由指向pages/Index点击运行即可在模拟器或真机上预览效果小贴士如果模拟器上没有数据展示请检查ForEach的movies数组是否正确初始化。项目总结本项目从零实现了电影追剧与观影记录应用的完整功能核心收获ArkTS 状态管理熟练使用State和数组不可变更新模式组件化思想通过Builder抽取可复用 UI代码更整洁深色主题设计掌握了多层级背景色搭配和卡片式设计技巧复杂布局ColumnRowGridTabsScroll的组合运用进阶方向建议接入真实 API如豆瓣电影、TMDB获取动态数据使用ObservedObjectLink实现更细粒度的响应式更新添加路由导航实现电影详情页集成 Preferences 或 RelationalStore 实现本地数据持久化使用Watch监听评分变化自动更新统计**完整源码可在上方的代码块中获取直接复制到 DevEco Studio 即可运行**等。