HarmonyOS 鸿蒙Next自然壁纸实战教程-视频列表
HarmonyOS 鸿蒙Next自然壁纸实战教程-视频列表
08-自然壁纸实战教程-视频列表
前言
视频列表页面本质上也是一个数据展示的列表,不同之处在于之前是是展示壁纸,Image组件负责渲染,这里展示的是视频,使用Video组件,另外视频页面也实现了下载的基本功能,由于视频往往比图片要大,所以这里的下载是比较耗时的,因此使用了多线程技术taskpool实现了视频的下载,并且保存到相册。
![视频列表页面]
视频搜索
![视频搜索]
这个模块其实是老模块了,这里直接提供代码
// 顶部搜索栏
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 })
视频分类
![视频分类]
视频分类页面也是一个常规的分类滚动结构,可以出用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": "🎵"
}
]
视频列表
![视频列表]
这里是视频列表,我们发送请求获取到视频数据后,使用 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)
如何获取资料
获取资料的途径,可以关注我们 官网的公众号 青蓝逐码 ,输入 项目名称 《自然壁纸》 即可获得以上资料。
![获取资料]
为什么需要关注公众号
如果我们的资源,网友连关注公众号的欲望都没有,说明我们的这个资料和资源也没有什么太大价值,那么不要也罢,可以让用户付出一些成本的,才是能证明有真正价值的东西。
关于我们
[关于青蓝逐码组织]
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。
![关于我们]
更多关于HarmonyOS 鸿蒙Next自然壁纸实战教程-视频列表的实战教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next自然壁纸实现视频列表功能,主要使用Video组件和ListContainer组件。在ets文件中,首先创建VideoItem类定义视频数据结构。通过@State装饰器管理视频列表数据,使用ForEach循环渲染ListContainer。每个ListItem包含Video组件,设置displayControls属性为false实现自动播放。通过onClick事件处理视频切换,使用currentTime方法控制播放进度。视频资源建议放在resources/base/media目录下,用$r引用。注意在config.json中声明ohos.permission.READ_MEDIA权限。
更多关于HarmonyOS 鸿蒙Next自然壁纸实战教程-视频列表的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个关于HarmonyOS Next开发中实现视频列表功能的详细教程。从技术实现来看,主要涉及以下几个关键点:
-
视频组件使用:使用Video组件替代Image组件来渲染视频内容,这是与图片列表的主要区别。
-
多线程下载:由于视频文件较大,使用taskpool实现多线程下载,避免阻塞UI线程。
-
列表优化:采用LazyForEach结合List实现高效渲染,并设置cachedCount为10来优化性能。
-
分类展示:通过Scroll组件实现横向分类滚动,使用ButtonType.Capsule样式展示分类标签。
-
导航跳转:点击视频卡片通过Navigation跳转到视频详情页。
代码结构清晰,展示了HarmonyOS ArkUI的声明式开发特点,包括组件嵌套、样式设置和事件处理等。特别是对视频缩略图、播放时长等细节的处理值得参考。
这个教程对于想学习HarmonyOS视频相关功能开发的开发者很有帮助,展示了从搜索、分类到列表展示的完整流程。