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

08-自然壁纸实战教程-视频列表-云

08-自然壁纸实战教程-视频列表

前言

视频列表页面本质上也是一个数据展示的列表,不同之处在于之前是是展示壁纸,Image组件负责渲染,这里展示的是视频,使用Video组件,另外视频页面也实现了下载的基本功能,由于视频往往比图片要大,所以这里的下载是比较耗时的,因此使用了多线程技术taskpool实现了视频的下载,并且保存到相册。

image-20250701081028571

视频搜索

image-20250701081116823

这个模块其实是老模块了,这里直接提供代码

  // 顶部搜索栏Row() {TextInput({ placeholder: '搜索视频...', text: $$this.videoViewModel.searchText }).width('80%').height(40).backgroundColor('#F5F5F5').borderRadius(20).padding({ left: 15, right: 15 }).onChange((text) => {this.videoViewModel.params.q = text}).onSubmit(async () => {await this.videoViewModel.search()})Button('搜索').width('18%').height(40).margin({ left: 8 }).borderRadius(20).backgroundColor('#3366CC').onClick(async () => {await this.videoViewModel.search()})}.width('100%').padding(10).margin({ top: 6 })

视频分类

image-20250701081239094

视频分类页面也是一个常规的分类滚动结构,可以出用Scroll组件完成基本结构

  Row() {Text('类型:').fontSize(16).fontWeight(FontWeight.Medium).margin({ right: 10 })// 使用Scroll实现横向滚动Scroll() {Row() {// 使用categories数据源ForEach(LocalData.CategoryData, (item: ICategory) => {Button({ type: ButtonType.Capsule }) {Text(item.text).fontSize(16).fontColor(this.videoViewModel.selectedCategory === item.value ? '#FFFFFF' : '#333333').padding({ left: 5, right: 5 })}.backgroundColor(this.videoViewModel.selectedCategory === item.value ? '#3366CC' : '#F0F0F0').margin({ right: 12 }).height(40).width('auto').padding({ left: 15, right: 15 }).onClick(() => {this.videoViewModel.selectCategory(item.value)})})}.width('auto')}.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off).width('80%').layoutWeight(1)}.width('100%').padding({ left: 10, right: 10, bottom: 10 }).alignItems(VerticalAlign.Center)

LocalData.CategoryData 数据源

  static readonly CategoryData: ICategory[] = [{"id": 0,"text": "背景","value": "backgrounds","icon": "🌅"},{"id": 1,"text": "时尚","value": "fashion","icon": "👔"},{"id": 2,"text": "自然","value": "nature","icon": "🌲"},{"id": 3,"text": "科学","value": "science","icon": "🔬"},{"id": 4,"text": "教育","value": "education","icon": "📚"},{"id": 5,"text": "感情","value": "feelings","icon": "❤️"},{"id": 6,"text": "健康","value": "health","icon": "🏥"},{"id": 7,"text": "人","value": "people","icon": "👥"},{"id": 8,"text": "宗教","value": "religion","icon": "🙏"},{"id": 9,"text": "地方","value": "places","icon": "🌆"},{"id": 10,"text": "动物","value": "animals","icon": "🐱"},{"id": 11,"text": "工业","value": "industry","icon": "🏭"},{"id": 12,"text": "计算机","value": "computer","icon": "💻"},{"id": 13,"text": "食品","value": "food","icon": "🍜"},{"id": 14,"text": "体育","value": "sports","icon": "🏃"},{"id": 15,"text": "交通","value": "transportation","icon": "🚗"},{"id": 16,"text": "旅行","value": "travel","icon": "✈️"},{"id": 17,"text": "建筑物","value": "buildings","icon": "🏢"},{"id": 18,"text": "商业","value": "business","icon": "💼"},{"id": 19,"text": "音乐","value": "music","icon": "🎵"}]

视频列表

image-20250701081326639

这里是视频列表,我们发送请求获取到视频数据后,使用 LazyForEach 结合 List 实现的视频列表渲染

      // 视频列表if (this.videoViewModel.videoList.totalCount() > 0) {List() {LazyForEach(this.videoViewModel.videoList, (video: VideoData, index: number) => {ListItem() {Column() {// 视频缩略图Stack() {Image(video.videos?.medium?.thumbnail || '').width('100%').height(200).borderRadius(8).objectFit(ImageFit.Cover)// 播放时长if (video.duration) {Text(CommonUtils.formatDuration(video.duration)).fontSize(12).fontColor($r('sys.color.comp_background_list_card')).backgroundColor('rgba(0, 0, 0, 0.6)').borderRadius(4).padding({left: 6,right: 6,top: 2,bottom: 2})}}.width('100%').alignContent(Alignment.BottomEnd)// 视频信息Row() {Column() {Text(video.tags.split(',')[0] || '未知标题').fontSize(16).fontWeight(FontWeight.Bold).margin({ top: 8, bottom: 4 }).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })Row() {Text(`${video.views || 0} 次观看`).fontSize(12).fontColor('#666666')Text(`${video.likes || 0}`).fontSize(12).fontColor('#666666').margin({ left: 10 })}}.alignItems(HorizontalAlign.Start).layoutWeight(1)}.width('100%').padding({left: 4,right: 4,top: 4,bottom: 8})}.width('100%').borderRadius(8).backgroundColor($r('sys.color.comp_background_list_card')).margin({ bottom: 12 })}.onAppear(() => {if (index == (this.videoViewModel.videoList.totalCount() - 5)) {this.videoViewModel.loadMore()}}).onClick(() => {NavigationUtils.getInstance().navigatePush(NavigationConst.Video_Player_View, video)})}, (video: VideoData, index: number) => video.id.toString())}.width('100%').layoutWeight(1).padding({ left: 10, right: 10 }).cachedCount(10)}

视频详情

视频详情是通过点击视频卡片,然后通过Navigation跳转实现的

 NavigationUtils.getInstance().navigatePush(NavigationConst.Video_Player_View, video)

关于我们

关于青蓝逐码组织

http://www.dtcms.com/a/272547.html

相关文章:

  • softmax公式推导
  • 深度学习中的批处理vs小批量训练
  • 大数据时代UI前端的智能化升级:基于机器学习的用户意图预测
  • MyBatis-Plus的LambdaQuery用法
  • 【音视频】HTTP协议介绍
  • 钉钉拿飞书当靶
  • 测试开发和后端开发到底怎么选?
  • 打破技术债困境:从“保持现状”到成为变革的推动者
  • VILA-M3: Enhancing Vision-Language Models with Medical Expert Knowledge
  • AI大模型平台
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_keepalive_time
  • 在虚拟机中安装Linux系统
  • EasyCVR视频汇聚平台国标接入设备TCP主动播放失败排查指南
  • 操作系统-IO多路复用
  • 深度学习核心:从基础到前沿的全面解析
  • 约束-1-约束
  • 【论文笔记】A Deep Reinforcement Learning Based Real-Time Solution Policy for the TSP
  • leetcode 226 翻转二叉树
  • openEuler 24.03 (LTS-SP1) 下安装 K8s 集群 + KubeSphere 遇到 etcd 报错的解决方案
  • Qt:按像素切割图片
  • 制胶学习分享
  • FFmpeg在Go、Python、C++、Rust实践案例
  • vue3 el-table 列汉字 排序时排除 null 或空字符串的值
  • rust cargo 编译双架构的库
  • 构建InfluxDB 3 Python插件深入实践指南
  • DDL期间TDSQL异常会话查询造成数据库主备切换
  • linux环境下安装和配置MySQL数据库
  • 关于市场主流自动化测试工具和框架的简要介绍
  • MySQL主键深度解析:数据库设计的核心基石
  • Java学习---JVM(1)