08-自然壁纸实战教程-视频列表-云
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)
关于我们
关于青蓝逐码组织