本节将演示如何在基于HarmonyOS ArkUI的List组件来实现音乐列表功能。
本文涉及的所有源码,均可以在文末链接中找到。
活动主页
https://developer.huawei.com/consumer/cn/forum/topic/0202126442505871313?fid=0101562279236410779
规则要求具体要求如下:
第1步:观看<HarmonyOS第一课>“营”在暑期•系列直播,一步步学会基于HarmonyOS最新版本的应用开发。
第2步:基于自适应布局和响应式布局,实现一次开发,多端部署音乐专辑,并成功完成展现音乐列表页的实现。如图所示:
创建应用
选择空模板。
创建名为ArkTSMusicPlayer的HarmonyOS应用。
核心代码讲解
主页
主页Index.ets 分为三部分:头部、中部、底部。
代码如下:
import { BreakpointConstants } from '../common/constants/BreakpointConstants'; import { StyleConstants } from '../common/constants/StyleConstants'; import { Content } from '../components/Content'; import { Header } from '../components/Header'; import { Player } from '../components/Player'; @Entry @Component struct Index { @State currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM; build() { Stack({ alignContent: Alignment.Top }) { // 头部 Header({ currentBreakpoint: $currentBreakpoint }) // 中部 Content({ currentBreakpoint: $currentBreakpoint }) // 底部 Player({ currentBreakpoint: $currentBreakpoint }) } .width(StyleConstants.FULL_WIDTH) } }复制
头部
头部Header.ets分为三部分:返回按钮、播放器名称、菜单。代码如下:
import router from '@ohos.router'; import { StyleConstants } from '../common/constants/StyleConstants'; import { HeaderConstants } from '../common/constants/HeaderConstants'; import { BreakpointType } from '../common/media/BreakpointSystem'; @Preview @Component export struct Header { @Link currentBreakpoint: string; build() { Row() { // 返回按钮 Image($r('app.media.ic_back')) .width($r('app.float.icon_width')) .height($r('app.float.icon_height')) .margin({ left: $r('app.float.icon_margin') }) .onClick(() => { router.back() }) // 播放器名称 Text($r('app.string.play_list')) .fontSize(new BreakpointType({ sm: $r('app.float.header_font_sm'), md: $r('app.float.header_font_md'), lg: $r('app.float.header_font_lg') }).getValue(this.currentBreakpoint)) .fontWeight(HeaderConstants.TITLE_FONT_WEIGHT) .fontColor($r('app.color.title_color')) .opacity($r('app.float.title_opacity')) .letterSpacing(HeaderConstants.LETTER_SPACING) .padding({ left: $r('app.float.title_padding_left') }) Blank() // 菜单 Image($r('app.media.ic_more')) .width($r('app.float.icon_width')) .height($r('app.float.icon_height')) .margin({ right: $r('app.float.icon_margin') }) //.bindMenu(this.getMenu()) } .width(StyleConstants.FULL_WIDTH) .height($r('app.float.title_bar_height')) .zIndex(HeaderConstants.Z_INDEX) } }复制
中部
头部Content.ets分为2部分:封面和歌曲列表。代码如下:
import { GridConstants } from '../common/constants/GridConstants'; import { StyleConstants } from '../common/constants/StyleConstants'; import { AlbumCover } from './AlbumCover'; import { PlayList } from './PlayList'; @Preview @Component export struct Content { @Link currentBreakpoint: string; build() { GridRow() { // 封面 GridCol({ span: { sm: GridConstants.SPAN_TWELVE, md: GridConstants.SPAN_SIX, lg: GridConstants.SPAN_FOUR } }) { AlbumCover({ currentBreakpoint: $currentBreakpoint }) } .backgroundColor($r('app.color.album_background')) // 歌曲列表 GridCol({ span: { sm: GridConstants.SPAN_TWELVE, md: GridConstants.SPAN_SIX, lg: GridConstants.SPAN_EIGHT } }) { PlayList({ currentBreakpoint: $currentBreakpoint }) } .borderRadius($r('app.float.playlist_border_radius')) } .height(StyleConstants.FULL_HEIGHT) .onBreakpointChange((breakpoints: string) => { this.currentBreakpoint = breakpoints; }) } }复制
其中,歌曲列表的核心是通过List组件实现的,核心代码如下:
build() { Column() { // 播放全部 this.PlayAll() // 歌单列表 List() { LazyForEach(new SongDataSource(this.songList), (item: SongItem, index: number) => { ListItem() { Column() { this.SongItem(item, index) } .padding({ left: $r('app.float.list_item_padding'), right: $r('app.float.list_item_padding') }) } }, (item, index) => JSON.stringify(item) + index) } .width(StyleConstants.FULL_WIDTH) .backgroundColor(Color.White) .margin({ top: $r('app.float.list_area_margin_top') }) .lanes(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? ContentConstants.COL_TWO : ContentConstants.COL_ONE) .layoutWeight(1) .divider({ color: $r('app.color.list_divider'), strokeWidth: $r('app.float.stroke_width'), startMargin: $r('app.float.list_item_padding'), endMargin: $r('app.float.list_item_padding') }) } .padding({ top: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 : $r('app.float.list_area_padding_top'), bottom: $r('app.float.list_area_padding_bottom') }) }复制
底部
底部就是歌曲播放器了。代码如下:
import { SongItem } from '../common/bean/SongItem'; import { PlayerConstants } from '../common/constants/PlayerConstants'; import { StyleConstants } from '../common/constants/StyleConstants'; import { BreakpointType } from '../common/media/BreakpointSystem'; import { MusicList } from '../common/media/MusicList'; @Preview @Component export struct Player { @StorageProp('selectIndex') selectIndex: number = 0; @StorageLink('isPlay') isPlay: boolean = false; songList: SongItem[] = MusicList; @Link currentBreakpoint: string; build() { Row() { Row() { Image(this.songList[this.selectIndex]?.label) .height($r('app.float.cover_height')) .width($r('app.float.cover_width')) .borderRadius($r('app.float.label_border_radius')) .margin({ right: $r('app.float.cover_margin') }) .rotate({ angle: this.isPlay ? PlayerConstants.ROTATE : 0 }) .animation({ duration: PlayerConstants.ANIMATION_DURATION, iterations: PlayerConstants.ITERATIONS, curve: Curve.Linear }) Column() { Text(this.songList[this.selectIndex].title) .fontColor($r('app.color.song_name')) .fontSize(new BreakpointType({ sm: $r('app.float.song_title_sm'), md: $r('app.float.song_title_md'), lg: $r('app.float.song_title_lg') }).getValue(this.currentBreakpoint)) Row() { Image($r('app.media.ic_vip')) .height($r('app.float.vip_icon_height')) .width($r('app.float.vip_icon_width')) .margin({ right: $r('app.float.vip_icon_margin') }) Text(this.songList[this.selectIndex].singer) .fontColor($r('app.color.singer')) .fontSize(new BreakpointType({ sm: $r('app.float.singer_title_sm'), md: $r('app.float.singer_title_md'), lg: $r('app.float.singer_title_lg') }).getValue(this.currentBreakpoint)) .opacity($r('app.float.singer_opacity')) } } .alignItems(HorizontalAlign.Start) } .layoutWeight(PlayerConstants.LAYOUT_WEIGHT_PLAYER_CONTROL) Blank() Row() { Image($r('app.media.ic_previous')) .height($r('app.float.control_icon_height')) .width($r('app.float.control_icon_width')) .margin({ right: $r('app.float.control_icon_margin') }) .displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO) Image(this.isPlay ? $r('app.media.ic_play') : $r('app.media.ic_pause')) .height($r('app.float.control_icon_height')) .width($r('app.float.control_icon_width')) .displayPriority(PlayerConstants.DISPLAY_PRIORITY_THREE) Image($r('app.media.ic_next')) .height($r('app.float.control_icon_height')) .width($r('app.float.control_icon_width')) .margin({ right: $r('app.float.control_icon_margin'), left: $r('app.float.control_icon_margin') }) .displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO) Image($r('app.media.ic_music_list')) .height($r('app.float.control_icon_height')) .width($r('app.float.control_icon_width')) .displayPriority(PlayerConstants.DISPLAY_PRIORITY_ONE) } .width(new BreakpointType({ sm: $r('app.float.play_width_sm'), md: $r('app.float.play_width_sm'), lg: $r('app.float.play_width_lg') }).getValue(this.currentBreakpoint)) .justifyContent(FlexAlign.End) } .width(StyleConstants.FULL_WIDTH) .height($r('app.float.player_area_height')) .backgroundColor($r('app.color.player_background')) .padding({ left: $r('app.float.player_padding'), right: $r('app.float.player_padding') }) .position({ x: 0, y: StyleConstants.FULL_HEIGHT }) .translate({ x: 0, y: StyleConstants.TRANSLATE_PLAYER_Y }) } }复制
效果演示
这个是竖版效果。
这个横板效果。
基于自适应布局和响应式布局,实现一次开发,多端部署。
完整视频演示见:https://www.bilibili.com/video/BV19z4y1T7XB/
源码
见:https://github.com/waylau/harmonyos-tutorial
学习更多HarmonyOS
作为开发者,及时投入HarmonyOS 4的学习是非常必要的。鸿蒙生态经历了艰难的四年,但轻舟已过万重山,目前已经慢慢走上了正轨,再现繁荣指日可待。
可以从HaromnyOS 官网(https://www.harmonyos.com/)了解到最新的HaromnyOS咨询以及开发指导。除此之外,笔者也整理了以下学习资料。
华为开发者联盟:https://developer.huawei.com/consumer/cn/forum/communityHome
《跟老卫学HarmonyOS开发》 开源免费教程:https://github.com/waylau/harmonyos-tutorial
《鸿蒙HarmonyOS手机应用开发实战》(清华大学出版社)
《鸿蒙HarmonyOS应用开发从入门到精通战》(北京大学出版社),
“鸿蒙系统实战短视频App 从0到1掌握HarmonyOS” :https://coding.imooc.com/class/674.html
共同学习,写下你的评论
评论加载中...
作者其他优质文章