偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

OpenHarmony仿視頻播放器應(yīng)用-愛電影(二)

系統(tǒng) OpenHarmony
簡(jiǎn)單來(lái)說(shuō)頁(yè)面分成上下兩部分,上半部分是一個(gè)橫向滾動(dòng)的banner,下半部分是電影資源的列表,列表中的一行兩列均分,每一個(gè)資源信息包括:電影資源的宣傳圖、電影名稱、演員、電影亮點(diǎn)。

??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??

??51CTO 開源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??

效果

??在線視頻??

接??上一篇??,閃屏頁(yè)面跳轉(zhuǎn)到主頁(yè),接下來(lái)我們?cè)敿?xì)的說(shuō)說(shuō)主頁(yè)開發(fā)涉及的內(nèi)容,首先我們來(lái)看下主頁(yè)是設(shè)計(jì)圖,如下:

#創(chuàng)作者激勵(lì)#OpenHarmony仿視頻播放器應(yīng)用-愛電影(二)-開源基礎(chǔ)軟件社區(qū)

簡(jiǎn)單來(lái)說(shuō)頁(yè)面分成上下兩部分,上半部分是一個(gè)橫向滾動(dòng)的banner,下半部分是電影資源的列表,列表中的一行兩列均分,每一個(gè)資源信息包括:電影資源的宣傳圖、電影名稱、演員、電影亮點(diǎn)。

項(xiàng)目開發(fā)

開發(fā)環(huán)境

硬件平臺(tái):DAYU2000 RK3568
系統(tǒng)版本:OpenHarmony 3.2 beta5
SDK:9(3.2.10.6)
IDE:DevEco Studio 3.1 Beta1 Build Version: 3.1.0.200, built on February 13, 2023

程序代碼

Index.ets

import { VideoDataSource } from '../model/VideoDataSource'
import { VideoData } from '../model/VideoData'
import { MockVideoData } from '../model/MockVideoData'
import router from '@ohos.router';
import { VideoListView } from '../view/VideoListView'
const TAG: string = 'Splash Index'
@Entry
@Component
struct Index {
@State bannerList: Array<VideoData> = []
@State videoList: Array<VideoData> = []
private scrollerForScroll: Scroller = new Scroller()
@State @Watch('scrollChange') scrollIndex: number = 0
@State opacity1: number = 0
aboutToAppear() {
this.initData()
router.clear()
}
scrollChange() {
if (this.scrollIndex === 0) {
this.scrollToAnimation(0, 0)
} else if (this.scrollIndex === 2) {
this.scrollToAnimation(0, 300)
}
}
scrollToAnimation(xOffset, yOffset) {
this.scrollerForScroll.scrollTo({
xOffset: xOffset,
yOffset: yOffset,
animation: {
duration: 3000,
curve: Curve.FastOutSlowIn
}
})
}
initData() {
this.bannerList = MockVideoData.getBannerList()
this.videoList = MockVideoData.getVideoList()
}
build() {
Column() {
Scroll(this.scrollerForScroll) {
Column() {
// banner
Swiper() {
LazyForEach(new VideoDataSource(this.bannerList), (item: VideoData) => {
Image(item.image)
.width('100%')
.height('100%')
.border({
radius: 20
})
.onClick(() => {
router.pushUrl({ url: 'pages/Playback',
params: {
video_data: item
} })
})
.objectFit(ImageFit.Fill)
}, item => item.id)
}
.width('100%')
.height(240)
.itemSpace(20)
.autoPlay(true)
.indicator(false)
.cachedCount(3)
.margin({
bottom: 20
})
VideoListView({
videoList: $videoList,
scrollIndex: $scrollIndex,
isBlackModule: false
})
}.width('100%')
}
.scrollBar(BarState.Off)
.scrollable(ScrollDirection.Vertical)
.scrollBarColor(Color.Gray)
.scrollBarWidth(30)
.edgeEffect(EdgeEffect.Spring)
}
.width('100%')
.height('100%')
.backgroundImage($r('app.media.main_bg'), ImageRepeat.XY)
.padding(20)
}
pageTransition() {
PageTransitionEnter({ duration: 1500,
type: RouteType.Push,
curve: Curve.Linear })
.opacity(this.opacity1)
.onEnter((type: RouteType, progress: number) => {
console.info(`${TAG} PageTransitionEnter onEnter type:${type} progress:${progress}`)
this.opacity1 = progress
})
}
}

開發(fā)詳解

1、電影數(shù)據(jù)

界面內(nèi)容需要通過(guò)數(shù)據(jù)進(jìn)行加載,目前沒有相關(guān)的電影云端,我們就先在本地mock出一些電影數(shù)據(jù),每個(gè)電影數(shù)據(jù)都應(yīng)該包含以下屬性,我們定義了一個(gè)類來(lái)表示:

VideoData.ets

export class VideoData {
id: string
name: string // 名稱
describe: string // 描述
resourceType: string // 資源類型 出品年限 類型
source:string // 來(lái)源
introduction: string // 介紹
uri: string | Resource // 資源地址
image: string | Resource // 資源圖片
actors: User[] //參演者
heat: number // 熱度
directs:User[] // 導(dǎo)演
grade:string // 評(píng)分
gradeNumber : string // 參與評(píng)分人數(shù)
}
export class User{
id: number
name: string
role: string
icon: string | Resource
}

2、構(gòu)建數(shù)據(jù)

溫馨提示:電影相關(guān)的數(shù)據(jù)是本地模擬,除了電影名稱和電影宣傳圖相關(guān),其他信息純屬虛構(gòu),如果你感興趣也可以自己構(gòu)建。

這個(gè)很簡(jiǎn)單,就是根據(jù)VideoData所定義的數(shù)據(jù),構(gòu)建出首頁(yè)需要顯示的內(nèi)容,因?yàn)閙ock的數(shù)據(jù)都是自定義的,所以這里就帖部分代碼,如果你有興趣可以自行構(gòu)造,如下所示:

MockVideoData.ets

export class MockVideoData {
static getVideoList(): Array<VideoData> {
let data: Array<VideoData> = new Array()
// 電影
data.push(this.createVideoDataByImage('鐵道英雄', $r('app.media.v1')))
data.push(this.createVideoDataByImage('沙丘', $r('app.media.v2')))
data.push(this.createVideoDataByImage('那一夜我給你開過(guò)車', $r('app.media.v3')))
data.push(this.createVideoDataByImage('雷神2', $r('app.media.v4')))
data.push(this.createVideoDataByImage('大圣歸來(lái)', $r('app.media.v5')))
data.push(this.createVideoDataByImage('流浪地球', $r('app.media.v6')))
data.push(this.createVideoDataByImage('狄仁杰', $r('app.media.v7')))
data.push(this.createVideoDataByImage('獨(dú)行月球', $r('app.media.v8')))
data.push(this.createVideoDataByImage('消失的子彈', $r('app.media.v9')))
data.push(this.createVideoDataByImage('西游降魔篇', $r('app.media.v10')))
data.push(this.createVideoDataByImage('激戰(zhàn)', $r('app.media.v11')))
data.push(this.createVideoDataByImage('作妖轉(zhuǎn)', $r('app.media.v12')))
data.push(this.createVideoDataByImage('滅絕', $r('app.media.v13')))
data.push(this.createVideoDataByImage('獨(dú)行月球', $r('app.media.v14')))
data.push(this.createVideoDataByImage('超人·素人特工', $r('app.media.v15')))
data.push(this.createVideoDataByImage('戰(zhàn)狼2', $r('app.media.v16')))
data.push(this.createVideoDataByImage('四大名捕', $r('app.media.v17')))
data.push(this.createVideoDataByImage('無(wú)人區(qū)', $r('app.media.v18')))
data.push(this.createVideoDataByImage('邪不壓正', $r('app.media.v19')))
return data
}
private static createVideoDataByImage(_name, _image, uri?): VideoData {
if (typeof (uri) === 'undefined') {
uri = $rawfile('video_4.mp4')
}
return this.createVideoData(
_name,
'硬漢強(qiáng)力回歸',
'2023 / 動(dòng)作 / 槍戰(zhàn)',
'愛電影',
'《邪不壓正》是由姜文編劇并執(zhí)導(dǎo),姜文、彭于晏、廖凡、周韻、許晴、澤田謙也等主演的動(dòng)作喜劇電影。該片改編自張北海小說(shuō)《俠隱》。講述在1937年\“七七事變\”爆發(fā)之前,北平城的“至暗時(shí)刻”,一個(gè)身負(fù)大恨、自美歸國(guó)的特工李天然,在國(guó)難之時(shí)滌蕩重重陰謀上演的一出終極復(fù)仇記。',
uri,
_image
)
}
private static createVideoData(_name, _describe, _resourceType, _source, _introduction, _uri, _image,): VideoData {
let vData: VideoData = new VideoData()
vData.id = UUIDUtils.getUUID()
vData.name = _name
vData.describe = _describe
vData.resourceType = _resourceType
vData.source = _source
vData.introduction = _introduction
vData.uri = _uri
vData.image = _image
vData.actors = []
let user1: User = new User()
user1.name = '吳京'
user1.role = '飾 吳曉曉'
user1.icon = $r('app.media.actor_02')
vData.actors.push(user1)
let user2: User = new User()
user2.name = '屈楚蕭'
user2.role = '飾 吳曉曉'
user2.icon = $r('app.media.actor_03')
vData.actors.push(user2)
let user3: User = new User()
user3.name = '吳京'
user3.role = '飾 吳曉曉'
user3.icon = $r('app.media.actor_02')
vData.actors.push(user3)
vData.heat = 89
vData.grade = '8.6'
vData.gradeNumber = '3.6萬(wàn)'
vData.directs = []
for (let i = 0; i < 1; i++) {
let user: User = new User()
user.name = '戴維'
user.role = '導(dǎo)演'
user.icon = $r('app.media.actor_01')
vData.directs.push(user)
}
return vData
}


static getBannerList(): Array<VideoData> {
let data: Array<VideoData> = new Array()
// 構(gòu)建banner數(shù)據(jù),與構(gòu)建videoData類似
return data
}
}

3、banner

在Index.ets的aboutToAppear()函數(shù)中初始化數(shù)據(jù),通過(guò)MockVideoData.getBannerList()獲取到banner列表,使用Swiper滑塊組件實(shí)現(xiàn)自動(dòng)輪播顯示。在Swiper容器中使用了LazyForEach懶加載的方式進(jìn)行子項(xiàng)的加載。簡(jiǎn)單說(shuō)明下LazyForEach懶加載機(jī)制,由于在長(zhǎng)列表渲染中會(huì)涉及到大量的數(shù)據(jù)加載,如果處理不當(dāng)會(huì)導(dǎo)致資源占用影響性能,在ArkUI3.0針對(duì)這樣的情況提供了一種懶加載機(jī)制,它會(huì)自動(dòng)根據(jù)具體的情況計(jì)算出適合渲染的數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的按需加載,提升UI刷新效率。

4、電影列表

在Index.ets的aboutToAppear()函數(shù)中初始化數(shù)據(jù),通過(guò)MockVideoData.getVideoList()獲取到Video列表,因?yàn)殡娪傲斜淼牟季衷陧?xiàng)目中其他模塊也會(huì)使用到,所以這里將電影列表抽象出一個(gè)子組件VideoListView。

VideoListView.ets

/**
* 視頻列表
*/
import { VideoData } from '../model/VideoData'
import { VideoDataSource } from '../model/VideoDataSource'
import { VideoDataUtils } from '../utils/VideoDataUtils'
import router from '@ohos.router';
const TAG: string = 'VideoListView'
@Component
export struct VideoListView {
private scrollerForGrid: Scroller = new Scroller()
@Link videoList: Array<VideoData>
@Link scrollIndex: number
@Prop isBlackModule: boolean //是否為黑色模式
build() {
// 電影列表
Grid(this.scrollerForGrid) {
LazyForEach(new VideoDataSource(this.videoList), (item: VideoData) => {
GridItem() {
Column() {
Image(item.image)
.width(200)
.height(250)
.objectFit(ImageFit.Cover)
.border({
width: this.isBlackModule ? 0 : 1,
color: '#5a66b1',
radius: 10
})
Text(item.name)
.width(200)
.height(20)
.fontColor(this.isBlackModule ? Color.Black : Color.White)
.fontSize(16)
.maxLines(1)
.textOverflow({
overflow: TextOverflow.Ellipsis
})
.margin({
top: 10
})
Text(VideoDataUtils.getUser(item.actors))
.width(200)
.height(20)
.fontColor(this.isBlackModule ? $r('app.color.name_black') : $r('app.color.name_grey'))
.fontSize(12)
.maxLines(1)
.textOverflow({
overflow: TextOverflow.Ellipsis
})
Text(item.describe)
.width(200)
.height(20)
.fontColor(this.isBlackModule ? $r('app.color.describe_black') : $r('app.color.describe_grey'))
.fontSize(12)
.maxLines(1)
.textOverflow({
overflow: TextOverflow.Ellipsis
})
}.width('100%')
.margin({
bottom: 10
})
.onClick(() => {
router.pushUrl({ url: 'pages/Playback',
params: {
video_data: item
} }, router.RouterMode.Single)
})
}
}, item => item.id)
}
.columnsTemplate('1fr 1fr')
.columnsGap(10)
.editMode(true)
.cachedCount(6)
.width('100%')
.height('100%')
.border({
width: 0,
color: Color.White
})
.onScrollIndex((first: number) => {
console.info(`${TAG} onScrollIndex ${first}`)
this.scrollIndex = first
if (first === 0) {
this.scrollerForGrid.scrollToIndex(0)
}
})
}
}

使用Grid實(shí)現(xiàn)電影列表,由于電影列表屬于長(zhǎng)列表數(shù)據(jù),所以這里也使用了LazyForEach懶加載機(jī)制進(jìn)行item子項(xiàng)的加載,最終通過(guò)import的方式引入到Index.ets頁(yè)面中,并在布局中添加此組件。

5、滾動(dòng)頁(yè)面

首頁(yè)是電影列表頁(yè),需要加載banner和電影列表,所以整體頁(yè)面都需要可滾動(dòng),因此在banner和視頻列表容器外添加了Scroll組件。

問題1:Scroll與Grid列表嵌套時(shí),電影列表無(wú)法顯示完整,或者無(wú)法顯示banner。

如下所示:

#創(chuàng)作者激勵(lì)#OpenHarmony仿視頻播放器應(yīng)用-愛電影(二)-開源基礎(chǔ)軟件社區(qū)

為了描述清楚這個(gè)問題,我們將界面可以觸發(fā)滑動(dòng)的區(qū)域分為banner部分和VideoList部分,根據(jù)滑動(dòng)的觸發(fā)區(qū)域不同,進(jìn)行如下說(shuō)明:

#創(chuàng)作者激勵(lì)#OpenHarmony仿視頻播放器應(yīng)用-愛電影(二)-開源基礎(chǔ)軟件社區(qū)

1、觸發(fā)滑動(dòng)區(qū)域在VideoList,當(dāng)滑動(dòng)到VideoList末尾時(shí)會(huì)出現(xiàn)最后一列的item只顯示了部分,滑動(dòng)區(qū)域在VideoList的時(shí)候無(wú)論怎么向上滑動(dòng)都無(wú)法顯示完整;

2、在1的場(chǎng)景下,觸發(fā)滑動(dòng)區(qū)域在banner,并向上滑動(dòng),此時(shí)可以看到,頁(yè)面整體向上移動(dòng),VideoList中缺失的item部分可以正常顯示,banner劃出界面時(shí),VideoList可以顯示完整;

3、在2的場(chǎng)景下,整個(gè)界面目前都是VideoList區(qū)域,VideoList已滑動(dòng)到的最后,此時(shí)向下滑動(dòng),因?yàn)橛|發(fā)的區(qū)域是VideoList,所以整個(gè)VideoList向下滑動(dòng)顯示,直到電影列表首項(xiàng),由于整個(gè)頁(yè)面的可滑動(dòng)區(qū)域都是VideoLIst,無(wú)法在觸發(fā)Scroll的滑動(dòng),所以banner無(wú)法顯示。

這個(gè)問題其實(shí)就是界面視圖高度計(jì)算和觸發(fā)滑動(dòng)監(jiān)聽被消費(fèi)后無(wú)法再向上層傳遞導(dǎo)致,解決這個(gè)問題有多種方式,下面我介紹其中一種。

解決方案:Scroll組件中可以添加一個(gè)Scroller滑動(dòng)組件的控制器,控制器可以控制組件的滾動(dòng),比如滾動(dòng)的指定高度,或者指定的index,在Grid中也可以添加一個(gè)Scroller控制器進(jìn)行列表高度控制,在Grid還可以通過(guò)onScrollIndex()事件監(jiān)聽網(wǎng)格顯示的起始位置item發(fā)生變化,返回當(dāng)前的item坐標(biāo)。當(dāng)滑動(dòng)區(qū)域在VideoList時(shí),如果item坐標(biāo)發(fā)生了變化,就更新scrollIndex,在Index.ets中監(jiān)聽scrollIndex的變化,當(dāng)scrollIndex=0時(shí)表示已經(jīng)滑動(dòng)到VideoList首項(xiàng),此時(shí)再向下滑動(dòng)時(shí)控制Scroll的控制器,讓Scroll滑動(dòng)到(0,0)位置,也就是頁(yè)面頂部,這樣就可以顯示banner;當(dāng)scrollIndex=2時(shí),表示VideoList向上滑動(dòng)到第二列,此時(shí)設(shè)置外層Scroll容器的滑動(dòng)高度,讓banner劃出界面,使得VideoList可以完整顯示。

實(shí)現(xiàn)核心代碼

1、Index.ets

import { VideoDataSource } from '../model/VideoDataSource'
import { VideoData } from '../model/VideoData'
import { MockVideoData } from '../model/MockVideoData'
import router from '@ohos.router';
import { VideoListView } from '../view/VideoListView'
const TAG: string = 'Splash Index'
@Entry
@Component
struct Index {
private scrollerForScroll: Scroller = new Scroller()
@State @Watch('scrollChange') scrollIndex: number = 0

scrollChange() {
if (this.scrollIndex === 0) {
this.scrollToAnimation(0, 0)
} else if (this.scrollIndex === 2) {
this.scrollToAnimation(0, 300)
}
}
scrollToAnimation(xOffset, yOffset) {
this.scrollerForScroll.scrollTo({
xOffset: xOffset,
yOffset: yOffset,
animation: {
duration: 3000,
curve: Curve.FastOutSlowIn
}
})
}

build() {
Column() {
Scroll(this.scrollerForScroll) {
Column() {
// banner
VideoListView({
videoList: $videoList,
scrollIndex: $scrollIndex,
isBlackModule: false
})
}.width('100%')
}
.scrollBar(BarState.Off)
.scrollable(ScrollDirection.Vertical)
.scrollBarColor(Color.Gray)
.scrollBarWidth(30)
.edgeEffect(EdgeEffect.Spring)
}
.width('100%')
.height('100%')
.backgroundImage($r('app.media.main_bg'), ImageRepeat.XY)
.padding(20)
}

}

2、VideoListView.ets

/**
* 視頻列表
*/
import { VideoData } from '../model/VideoData'
import { VideoDataSource } from '../model/VideoDataSource'
import { VideoDataUtils } from '../utils/VideoDataUtils'
import router from '@ohos.router';

const TAG: string = 'VideoListView'

@Component
export struct VideoListView {
private scrollerForGrid: Scroller = new Scroller()
@Link scrollIndex: number

build() {
// 電影列表
Grid(this.scrollerForGrid) {
LazyForEach(new VideoDataSource(this.videoList), (item: VideoData) => {
GridItem() {
// item
}.width('100%')
.margin({
bottom: 10
})
.onClick(() => {
router.pushUrl({ url: 'pages/Playback',
params: {
video_data: item
} }, router.RouterMode.Single)
})
}

}, item => item.id)
}
.columnsTemplate('1fr 1fr')
.columnsGap(10)
.editMode(true)
.cachedCount(6)
.width('100%')
.height('100%')
.border({
width: 0,
color: Color.White
})
.onScrollIndex((first: number) => {
console.info(`${TAG} onScrollIndex ${first}`)
this.scrollIndex = first
if (first === 0) {
this.scrollerForGrid.scrollToIndex(0)
}
})
}
}

??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??

??51CTO 開源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??

責(zé)任編輯:jianghua 來(lái)源: 51CTO 開源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-03-29 09:32:15

視頻播放器應(yīng)用鴻蒙

2023-03-29 09:37:49

視頻播放器應(yīng)用鴻蒙

2023-03-28 09:38:34

開發(fā)應(yīng)用鴻蒙

2022-08-16 17:37:06

視頻播放器鴻蒙

2015-09-01 16:48:44

ios暴風(fēng)視頻播放器

2021-10-21 16:00:07

鴻蒙HarmonyOS應(yīng)用

2011-07-20 16:21:20

iPhone 視頻 播放器

2015-05-21 15:25:42

VLC播放器

2015-01-22 15:44:55

Android源碼音樂播放器

2022-06-21 14:41:38

播放器適配西瓜視頻

2021-10-19 14:27:07

鴻蒙HarmonyOS應(yīng)用

2022-11-12 08:26:04

VLC視頻播放器裁剪視頻

2018-05-25 14:37:58

2023-03-06 16:20:08

視頻播放器VLC

2023-08-26 19:07:40

VLC旋轉(zhuǎn)視頻

2022-01-27 08:12:50

Potplayer播放器

2011-06-13 09:33:04

2012-06-04 13:44:08

2015-01-19 13:52:38

Android源碼多功能播放器

2011-06-27 11:23:21

Qt 音樂播放器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)