鸿蒙原生应用开发实战(四):电影详情与评分评价 — 电影清单App
2026/6/11 21:24:59 网站建设 项目流程

鸿蒙原生应用开发实战(四):电影详情与评分评价 — 电影清单App

前言

前三篇文章我们完成了首页、添加电影和列表页面。当用户点击某部电影时,需要进入详情页面查看完整信息、打分和写影评。这篇文章将开发电影详情页,这是最富交互性的页面。

本文涵盖:

  1. 路由传参接收电影ID
  2. 电影信息展示布局
  3. 五角星评分组件
  4. 状态切换与收藏
  5. 影评编辑(TextArea)
  6. 数据更新与删除

一、详情页面设计

┌──────────────────────────────────┐ │ < 返回 电影详情 │ ├──────────────────────────────────┤ │ 🚀 │ │ 星际穿越 │ │ 2014 · 科幻 │ │ 导演: 克里斯托弗·诺兰 │ ├──────────────────────────────────┤ │ [👀 想看] [▶️ 在看] [✅ 已看] │ ← 状态切换 ├──────────────────────────────────┤ │ ⭐ 已收藏 [🔲] │ ← 收藏开关 ├──────────────────────────────────┤ │ 我的评分 │ │ ★★★★★ │ ← 星级显示 │ ★ ☆ ☆ ☆ ☆ │ ← 点击评分 ├──────────────────────────────────┤ │ 我的影评 编辑 │ ← 展开编辑 │ 时间、空间与爱的史诗。 │ ├──────────────────────────────────┤ │ 添加日期: 2025-01-12 │ │ │ │ [ 删除这部电影 ] │ └──────────────────────────────────┘

二、路由传参

2.1 跳转传参

从列表页或首页跳转到详情页时传递电影ID:

router.pushUrl({url:'pages/DetailPage',params:{movieId:item.id}});

2.2 接收参数

在详情页的aboutToAppear中接收参数:

aboutToAppear():void{letparams=router.getParams()asRecord<string,Object>;letmovieId=params['movieId']asstring;letstored=AppStorage.get<Movie[]>('movies');if(stored){this.movies=stored;for(leti=0;i<stored.length;i++){if(stored[i].id===movieId){this.movie=stored[i];this.editReview=stored[i].review;break;}}}}

2.3 状态定义

@Entry@Componentstruct DetailPage{@Statemovie:Movie={id:'',title:'',year:0,director:'',rating:0,status:MovieStatus.WANT_TO_WATCH,isFavorite:false,review:'',dateAdded:'',genreId:''};@Statemovies:Movie[]=[];@StateeditReview:string='';@StateshowReviewInput:boolean=false;}

三、电影信息展示

3.1 标题区域

Column(){Text(getGenreById(this.movie.genreId)?.icon??'🎬').fontSize(56).margin({bottom:8})Text(this.movie.title).fontSize(24).fontWeight(FontWeight.Bold).fontColor('#333333').textAlign(TextAlign.Center)Text(this.movie.year+' · '+(getGenreById(this.movie.genreId)?.name??'未知')).fontSize(14).fontColor('#999999').margin({top:4})Text('导演: '+(this.movie.director?this.movie.director:'未知')).fontSize(14).fontColor('#999999').margin({top:2})}.width('100%').padding(20).backgroundColor('#FFFFFF').alignItems(HorizontalAlign.Center)

3.2 状态切换

@BuilderstatusBtn(label:string,status:MovieStatus){Text(label).fontSize(13).fontColor(this.movie.status===status?'#FFFFFF':'#666666').backgroundColor(this.movie.status===status?'#6C63FF':'#F0F0F0').padding({left:12,right:12,top:6,bottom:6}).borderRadius(14).margin({right:6}).onClick(()=>{this.changeStatus(status);})}

四、收藏功能

4.1 Toggle 开关

使用 HarmonyOS 的 Toggle 组件实现收藏开关:

Row(){Text(this.movie.isFavorite?'⭐ 已收藏':'🤍 收藏').fontSize(16).fontColor(this.movie.isFavorite?'#FFA502':'#999999')Blank()Toggle({type:ToggleType.Checkbox,isOn:this.movie.isFavorite}).onChange((v:boolean)=>{this.movie.isFavorite=v;this.saveMovieData();})}.width('94%').padding(14).backgroundColor('#FFFFFF').borderRadius(12).margin({top:10})

4.2 数据持久化

每次状态变化立即保存到 AppStorage:

saveMovieData():void{letupdated=false;for(leti=0;i<this.movies.length;i++){if(this.movies[i].id===this.movie.id){this.movies[i]=this.movie;updated=true;break;}}if(!updated){this.movies.push(this.movie);}AppStorage.set<Movie[]>('movies',this.movies);}

五、星级评分组件

5.1 星级显示

使用 unicode 字符 ★☆ 显示评分:

exportfunctionstarsString(rating:number):string{letfull='★'.repeat(rating);letempty='☆'.repeat(5-rating);returnfull+empty;}

5.2 可点击评分

Text('我的评分').fontSize(14).fontColor('#999999').width('100%')// ★★★★★ 显示当前评分Row(){Text(starsString(this.movie.rating)).fontSize(32).fontColor('#FFA502').letterSpacing(4)}.width('100%').margin({top:6})// 可点击的星星Row(){this.starBtn(1)this.starBtn(2)this.starBtn(3)this.starBtn(4)this.starBtn(5)}.width('100%').margin({top:6})

5.3 星星按钮

@BuilderstarBtn(rating:number){Text(rating<=this.movie.rating?'★':'☆').fontSize(30).fontColor('#FFA502').margin({right:4}).onClick(()=>{this.setRating(rating);})}

点击时更新评分并保存:

setRating(r:number):void{this.movie.rating=r;this.saveMovieData();}

六、影评编辑

6.1 文本编辑区

点击「编辑」按钮展开 TextArea 输入区:

Column(){Row(){Text('我的影评').fontSize(14).fontColor('#999999')Blank()Text('编辑').fontSize(13).fontColor('#6C63FF').onClick(()=>{this.editReview=this.movie.review;this.showReviewInput=!this.showReviewInput;})}.width('100%')if(this.showReviewInput){TextArea({placeholder:'写下你的影评...',text:this.editReview}).fontSize(15).height(100).width('100%').placeholderColor('#CCCCCC').backgroundColor('#F9F9F9').margin({top:8}).onChange((v:string)=>{this.editReview=v;})Button('保存影评').width('100%').height(36).backgroundColor('#6C63FF').borderRadius(18).fontSize(14).fontColor('#FFFFFF').margin({top:6}).onClick(()=>{this.saveReview();})}else{Text(this.movie.review?this.movie.review:'暂无影评,点击编辑添加...').fontSize(15).fontColor(this.movie.review?'#333333':'#CCCCCC').width('100%').margin({top:6})}}

6.2 保存影评

saveReview():void{this.movie.review=this.editReview;this.showReviewInput=false;this.saveMovieData();}

七、删除功能

7.1 删除按钮

Button('删除这部电影').width('94%').height(44).backgroundColor('#FFFFFF').fontColor('#FF4757').fontSize(16).borderRadius(22).border({width:1,color:'#FF4757'}).margin({top:16,bottom:30}).onClick(()=>{this.deleteMovie();})

7.2 删除逻辑

deleteMovie():void{letnewList:Movie[]=[];for(leti=0;i<this.movies.length;i++){if(this.movies[i].id!==this.movie.id){newList.push(this.movies[i]);}}AppStorage.set<Movie[]>('movies',newList);router.back();}

八、完整交互流程

用户点击电影卡片 → ListPage pushUrl 传递 movieId → DetailPage aboutToAppear 读取参数 → 从 AppStorage 查找对应电影 → 展示完整信息 用户修改评分/状态/收藏 → 立即更新 @State movie → 调用 saveMovieData() 保存到 AppStorage → 数据实时持久化 用户编辑影评 → 点击「编辑」展开 TextArea → 输入内容后点击「保存影评」 → 数据保存并收起编辑区 用户删除电影 → 点击「删除这部电影」 → 从列表中移除 → 更新 AppStorage → 返回列表页

九、ArkTS 注意事项

9.1 对象初始化

由于 ArkTS 严格模式要求对象字面量有显式类型,初始化@State movie时需要完整赋值:

@Statemovie:Movie={id:'',title:'',year:0,director:'',rating:0,status:MovieStatus.WANT_TO_WATCH,isFavorite:false,review:'',dateAdded:'',genreId:''};

9.2 路由参数类型转换

router.getParams()返回的类型需要用as Record<string, Object>断言,再取值:

letparams=router.getParams()asRecord<string,Object>;letmovieId=params['movieId']asstring;

总结

本文完成了电影详情页面的开发:

  • ✅ 路由传参与数据加载
  • ✅ 状态切换(想看/在看/已看)
  • ✅ 收藏功能(Toggle + 实时保存)
  • ✅ 星级评分组件(点击评分)
  • ✅ 影评编辑(TextArea 展开/收起)
  • ✅ 删除功能

至此,应用的 CRUD(增删改查)已经全部实现!下一篇将开发个人中心页面,完成数据统计和分类分析!


系列目录

  • ✅ 第一篇:项目搭建与首页概览
  • ✅ 第二篇:添加电影与表单交互
  • ✅ 第三篇:电影列表与搜索筛选
  • ✅ 第四篇:电影详情与评分评价(本篇)
  • 📝 第五篇:个人中心与数据统计

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询