介紹
主要介紹了滑動容器組件Swiper的幾種常見的應用場景,包括頂部導航、輪播圖以及視頻滑動播放。
相關概念
- [Swiper]:滑動容器,提供子組件切換滑動的能力。
- [Stack]:堆疊容器,子組件按照順序依次入棧,后入棧組件在先入棧組件上方顯示。
- [Video]:視頻播放組件。
- [Observed和ObjectLink數(shù)據(jù)管理]:
- @Observed應用于類,表示該類中的數(shù)據(jù)變更被UI頁面管理,例如:@Observed class ClassA {}。
- @ObjectLink應用于被@Observed所裝飾類的對象,例如:@ObjectLink a: ClassA。
環(huán)境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 開發(fā)板類型:[潤和RK3568開發(fā)板]。
- OpenHarmony系統(tǒng):3.2 Release。
環(huán)境搭建
完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:
- [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
- 搭建燒錄環(huán)境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開發(fā)板的燒錄]
- 搭建開發(fā)環(huán)境。
代碼結構解讀
本篇Codelab只對核心代碼進行講解,完整代碼可以直接從gitee獲取。
├──entry/src/main/ets // 代碼區(qū)
│ ├──common
│ │ └──constants
│ │ ├──CommonConstant.ets // 公共常量
│ │ ├──PictureConstants.ets // 圖片所使用的常量
│ │ ├──TopBarConstants.ets // TopBar使用的常量
│ │ └──VideoConstants.ets // Video使用的常量
│ ├──entryability
│ │ └──EntryAbility.ts // 程序入口類
│ ├──pages
│ │ ├──PageVideo.ets // 視頻播放頁
│ │ └──SwiperIndex.ets // 應用首頁
│ ├──view
│ │ ├──all
│ │ │ └──PictureSort.ets // “全部”tab頁圖片類別組件
│ │ ├──common
│ │ │ ├──Banner.ets // 輪播圖組件
│ │ │ ├──PictureView.ets // 圖片組件
│ │ │ └──TopBar.ets // 頂部導航組件
│ │ ├──movie
│ │ │ └──MovieSort.ets // “電影”tab頁圖片類別組件
│ │ ├──play // 視頻播放組件目錄
│ │ │ ├──CommentView.ets // 評論模塊組件
│ │ │ ├──DescriptionView.ets // 視頻描述信息組件
│ │ │ ├──NavigationView.ets // 頂部返回導航組件
│ │ │ └──PlayView.ets // 視頻滑動播放組件
│ │ └──tabcontent // tab內(nèi)容組件
│ │ ├──PageAll.ets // 全部tab頁
│ │ ├──PageEntertainment.ets // 娛樂tab頁
│ │ ├──PageGame.ets // 游戲tab頁
│ │ ├──PageLive.ets // 直播tab頁
│ │ ├──PageMovie.ets // 電影tab頁
│ │ └──PageTV.ets // 電視tab頁
│ └──viewmodel
│ ├──PictureItem.ets // 圖片對象
│ ├──PictureViewModel.ets // 圖片模型
│ ├──TopBarItem.ets // 頂部導航對象
│ ├──TopBarViewModel.ets // 頂部導航模型
│ ├──VideoItem.ets // 視頻對象
│ └──VideoViewModel.ets // 視頻模型
└──entry/src/main/resources // 應用資源目錄
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
頂部導航場景
應用首頁首頁使用Swiper組件實現(xiàn)了頂部導航的應用場景。用戶點擊不同的分類標題,會切換展示不同的界面內(nèi)容。同時也支持用戶左右滑動界面,對應導航標題聯(lián)動變化的效果。
實現(xiàn)這種效果,我們只需將界面劃分為兩部分:導航欄與內(nèi)容區(qū)。導航欄使用自定義組件TopBar實現(xiàn),內(nèi)容區(qū)使用Swiper組件實現(xiàn)。
@State和@Link裝飾符配合使用,實現(xiàn)TopBar組件標題與Swiper組件索引的雙向綁定。內(nèi)容區(qū)內(nèi)容滑動時,會觸發(fā)Swiper的onChange事件,并改變索引index的值。前面已經(jīng)通過特定修飾符實現(xiàn)了索引的雙向綁定。因此該索引值的變化會使TopBar的索引值同步變化,實現(xiàn)TopBar和Swiper的聯(lián)動效果。
// SwiperIndex.ets
struct SwiperIndex {
// 索引值雙向綁定 實現(xiàn)聯(lián)動效果.
@State index: number = 0;
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
TopBar({ index: $index })
Swiper() {
PageAll()
PageMovie()
PageTV()
PageEntertainment()
PageLive()
PageGame()
}
.index(this.index)
.indicator(false)
.loop(false)
.onChange((index: number) = > {
this.index = index;
})
}
.backgroundColor($r('app.color.start_window_background'))
}
}
點擊導航欄中的不同標題時,會觸發(fā)TopBar中的onClick事件,并改變對應的索引值。同理,該索引的變化會使Swiper的索引值同步變化,實現(xiàn)Swiper和TopBar的聯(lián)動效果。
// TopBar.ets
export struct TopBar {
// 索引值雙向綁定 實現(xiàn)聯(lián)動效果
@Link index: number;
private tabArray: Array< TopBarItem > = initializeOnStartup();
build() {
Row({ space: CommonConstants.SPACE_TOP_BAR }) {
ForEach(this.tabArray,
(item: TopBarItem) = > {
Text(item.name)
.fontSize(this.index === item.id ? $r('app.float.font_size_checked') : $r('app.float.font_size_unchecked'))
.fontColor(Color.Black)
.textAlign(TextAlign.Center)
.fontWeight(this.index === item.id ? FontWeight.Bold : FontWeight.Regular)
.onClick(() = > {
this.index = item.id;
})
}, (item: TopBarItem) = > JSON.stringify(item))
}
.margin({ left: CommonConstants.ADS_LEFT })
.width(CommonConstants.FULL_WIDTH)
.height(CommonConstants.TOP_BAR_HEIGHT)
}
}
最終實現(xiàn)導航欄與內(nèi)容區(qū)的雙向聯(lián)動效果。
輪播圖場景
輪播圖常見于各種應用首頁,用于各類信息、資訊的輪番展示。本應用使用Swiper組件,同樣實現(xiàn)了這一能力。“全部”頁簽的“電影精選”部分,即為一個電影內(nèi)容的輪播模塊。它可以切換展示不同電影內(nèi)容。
我們將輪播圖模塊定義為一個自定義組件Banner。在Banner組件創(chuàng)建新實例時,會初始化輪播內(nèi)容并開啟定時任務。定時任務通過調用swiperController.showNext()方法,控制Swiper組件切換內(nèi)容展示。
// Banner.ets
aboutToAppear() {
// 內(nèi)容數(shù)據(jù)初始化
this.imageArray = initializePictures(PictureType.BANNER);
// 開啟定時輪播
startPlay(this.swiperController);
}
// PictureViewModel.ets
export function startPlay(swiperController: SwiperController) {
let timerId = setInterval(() = > {
swiperController.showNext();
}, CommonConstants.SWIPER_TIME);
timerIds.push(timerId);
}
在Swiper組件內(nèi),將初始化數(shù)據(jù)進行循環(huán)渲染。配合開啟的定時任務,循環(huán)播放。
// Banner.ets
build() {
Swiper(this.swiperController) {
ForEach(this.imageArray, (item: PictureItem) = > {
Stack({ alignContent: Alignment.TopStart }) {
Image(item.image)
...
Column() {
Text($r('app.string.movie_classic'))
.textStyle($r('app.float.font_size_description'), CommonConstants.FONT_WEIGHT_LIGHT)
...
Text(item.name)
.textStyle($r('app.float.font_size_title'), CommonConstants.FONT_WEIGHT_BOLD)
}
...
}
.height(CommonConstants.FULL_HEIGHT)
.width(CommonConstants.FULL_WIDTH)
}, (item: PictureItem) = > JSON.stringify(item))
}
...
}
視頻滑動播放場景
視頻滑動播放是Swiper組件的另一個常見應用場景。點擊應用首頁中的視頻圖片,會跳轉至視頻播放界面。我們可以通過上下滑動,切換播放的視頻內(nèi)容。
視頻播放界面通過函數(shù)initializeOnStartup初始化視頻內(nèi)容。在Swiper組件內(nèi)通過循環(huán)渲染的方式,將各個視頻內(nèi)容渲染成自定義組件PlayView。這樣每一個視頻內(nèi)容就是一個Swiper的子組件,就可以通過滑動的方式切換播放內(nèi)容。
// PageVideo.ets
build() {
Column() {
Swiper() {
ForEach(this.videoArray, (item: VideoItem, index: number) = > {
PlayView({
index: $index,
pageShow: $pageShow,
item: item,
barPosition: index
});
}, (item: VideoItem) = > JSON.stringify(item))
}
.width(CommonConstants.FULL_WIDTH)
.height(CommonConstants.FULL_HEIGHT)
.indicator(false)
.loop(false)
.vertical(true)
.onChange((index: number) = > {
this.index = index;
})
}
}
在自定義組件PlayView中,通過Video來控制視頻播放。另外,結合Stack容器組件,在視頻內(nèi)容上疊加點贊、評論、轉發(fā)等內(nèi)容。
// PlayView.ets
build() {
Stack({ alignContent: Alignment.End }) {
Video({
src: this.item.src,
controller: this.videoController
})
.controls(false)
.autoPlay(this.playState === PlayState.START ? true : false)
.objectFit(ImageFit.Fill)
.loop(true)
.height(CommonConstants.WIDTH_VIDEO)
.width(CommonConstants.FULL_WIDTH)
.onClick(() = > {
if (this.playState === PlayState.START) {
this.playState = PlayState.PAUSE;
this.videoController.pause();
} else if (this.playState === PlayState.PAUSE) {
this.playState = PlayState.START;
this.videoController.start();
}
})
NavigationView()
CommentView({ item: this.item })
DescriptionView()
}
.backgroundColor(Color.Black)
.width(CommonConstants.FULL_WIDTH)
.height(CommonConstants.FULL_HEIGHT)
}
審核編輯 黃宇
-
鴻蒙
+關注
關注
60文章
2623瀏覽量
44076 -
HarmonyOS
+關注
關注
80文章
2126瀏覽量
33153
發(fā)布評論請先 登錄
OpenHarmony實戰(zhàn)開發(fā)-swiper開發(fā)指導
鴻蒙5開發(fā)寶藏案例分享---Swiper組件性能優(yōu)化實戰(zhàn)
《labview入門與實戰(zhàn)開發(fā)》經(jīng)典案例
HarmonyOS測試技術與實戰(zhàn)-HarmonyOS分布式應用特征與挑戰(zhàn)

HarmonyOS測試技術與實戰(zhàn)-HarmonyOS圖形棧測試技術深度解析

HarmonyOS測試技術與實戰(zhàn)-HarmonyOS圖形棧整體架構和測試能力

HarmonyOS測試技術與實戰(zhàn)-華為ArkUI開發(fā)框架和場景測試

HarmonyOS測試技術與實戰(zhàn)-HarmonyOS自研圖形??偨Y

華為開發(fā)者分論壇HarmonyOS學生公開課-OpenHarmony Codelabs開發(fā)案例

評論