当前位置:   article > 正文

基于HarmonyOS ArkUI实现音乐列表功能_breakpointconstants

breakpointconstants

本节将演示如何在基于HarmonyOS ArkUI的List组件来实现音乐列表功能。

本文涉及的所有源码,均可以在文末链接中找到。

活动主页

华为开发者论坛

规则要求具体要求如下:

  • 第1步:观看<HarmonyOS第一课>“营”在暑期•系列直播,一步步学会基于HarmonyOS最新版本的应用开发。
  • 第2步:基于自适应布局和响应式布局,实现一次开发,多端部署音乐专辑,并成功完成展现音乐列表页的实现。如图所示:

创建应用

选择空模板。

cke_206.png

创建名为ArkTSMusicPlayer的HarmonyOS应用。

cke_207.png

核心代码讲解

主页

主页Index.ets 分为三部分:头部、中部、底部。

cke_208.png

代码如下:

  1. import { BreakpointConstants } from '../common/constants/BreakpointConstants';
  2. import { StyleConstants } from '../common/constants/StyleConstants';
  3. import { Content } from '../components/Content';
  4. import { Header } from '../components/Header';
  5. import { Player } from '../components/Player';
  6. @Entry
  7. @Component
  8. struct Index {
  9. @State currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM;
  10. build() {
  11. Stack({ alignContent: Alignment.Top }) {
  12. // 头部
  13. Header({ currentBreakpoint: $currentBreakpoint })
  14. // 中部
  15. Content({ currentBreakpoint: $currentBreakpoint })
  16. // 底部
  17. Player({ currentBreakpoint: $currentBreakpoint })
  18. }
  19. .width(StyleConstants.FULL_WIDTH)
  20. }
  21. }
复制

头部

头部Header.ets分为三部分:返回按钮、播放器名称、菜单。代码如下:

  1. import router from '@ohos.router';
  2. import { StyleConstants } from '../common/constants/StyleConstants';
  3. import { HeaderConstants } from '../common/constants/HeaderConstants';
  4. import { BreakpointType } from '../common/media/BreakpointSystem';
  5. @Preview
  6. @Component
  7. export struct Header {
  8. @Link currentBreakpoint: string;
  9. build() {
  10. Row() {
  11. // 返回按钮
  12. Image($r('app.media.ic_back'))
  13. .width($r('app.float.icon_width'))
  14. .height($r('app.float.icon_height'))
  15. .margin({ left: $r('app.float.icon_margin') })
  16. .onClick(() => {
  17. router.back()
  18. })
  19. // 播放器名称
  20. Text($r('app.string.play_list'))
  21. .fontSize(new BreakpointType({
  22. sm: $r('app.float.header_font_sm'),
  23. md: $r('app.float.header_font_md'),
  24. lg: $r('app.float.header_font_lg')
  25. }).getValue(this.currentBreakpoint))
  26. .fontWeight(HeaderConstants.TITLE_FONT_WEIGHT)
  27. .fontColor($r('app.color.title_color'))
  28. .opacity($r('app.float.title_opacity'))
  29. .letterSpacing(HeaderConstants.LETTER_SPACING)
  30. .padding({ left: $r('app.float.title_padding_left') })
  31. Blank()
  32. // 菜单
  33. Image($r('app.media.ic_more'))
  34. .width($r('app.float.icon_width'))
  35. .height($r('app.float.icon_height'))
  36. .margin({ right: $r('app.float.icon_margin') })
  37. //.bindMenu(this.getMenu())
  38. }
  39. .width(StyleConstants.FULL_WIDTH)
  40. .height($r('app.float.title_bar_height'))
  41. .zIndex(HeaderConstants.Z_INDEX)
  42. }
  43. }
复制

中部

头部Content.ets分为2部分:封面和歌曲列表。代码如下:

 

  1. import { GridConstants } from '../common/constants/GridConstants';
  2. import { StyleConstants } from '../common/constants/StyleConstants';
  3. import { AlbumCover } from './AlbumCover';
  4. import { PlayList } from './PlayList';
  5. @Preview
  6. @Component
  7. export struct Content {
  8. @Link currentBreakpoint: string;
  9. build() {
  10. GridRow() {
  11. // 封面
  12. GridCol({ span: { sm: GridConstants.SPAN_TWELVE, md: GridConstants.SPAN_SIX, lg: GridConstants.SPAN_FOUR } }) {
  13. AlbumCover({ currentBreakpoint: $currentBreakpoint })
  14. }
  15. .backgroundColor($r('app.color.album_background'))
  16. // 歌曲列表
  17. GridCol({ span: { sm: GridConstants.SPAN_TWELVE, md: GridConstants.SPAN_SIX, lg: GridConstants.SPAN_EIGHT } }) {
  18. PlayList({ currentBreakpoint: $currentBreakpoint })
  19. }
  20. .borderRadius($r('app.float.playlist_border_radius'))
  21. }
  22. .height(StyleConstants.FULL_HEIGHT)
  23. .onBreakpointChange((breakpoints: string) => {
  24. this.currentBreakpoint = breakpoints;
  25. })
  26. }
  27. }
复制

其中,歌曲列表的核心是通过List组件实现的,核心代码如下:

  1. build() {
  2. Column() {
  3. // 播放全部
  4. this.PlayAll()
  5. // 歌单列表
  6. List() {
  7. LazyForEach(new SongDataSource(this.songList), (item: SongItem, index: number) => {
  8. ListItem() {
  9. Column() {
  10. this.SongItem(item, index)
  11. }
  12. .padding({
  13. left: $r('app.float.list_item_padding'),
  14. right: $r('app.float.list_item_padding')
  15. })
  16. }
  17. }, (item, index) => JSON.stringify(item) + index)
  18. }
  19. .width(StyleConstants.FULL_WIDTH)
  20. .backgroundColor(Color.White)
  21. .margin({ top: $r('app.float.list_area_margin_top') })
  22. .lanes(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
  23. ContentConstants.COL_TWO : ContentConstants.COL_ONE)
  24. .layoutWeight(1)
  25. .divider({
  26. color: $r('app.color.list_divider'),
  27. strokeWidth: $r('app.float.stroke_width'),
  28. startMargin: $r('app.float.list_item_padding'),
  29. endMargin: $r('app.float.list_item_padding')
  30. })
  31. }
  32. .padding({
  33. top: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 : $r('app.float.list_area_padding_top'),
  34. bottom: $r('app.float.list_area_padding_bottom')
  35. })
  36. }
复制

底部

底部就是歌曲播放器了。代码如下:

  1. import { SongItem } from '../common/bean/SongItem';
  2. import { PlayerConstants } from '../common/constants/PlayerConstants';
  3. import { StyleConstants } from '../common/constants/StyleConstants';
  4. import { BreakpointType } from '../common/media/BreakpointSystem';
  5. import { MusicList } from '../common/media/MusicList';
  6. @Preview
  7. @Component
  8. export struct Player {
  9. @StorageProp('selectIndex') selectIndex: number = 0;
  10. @StorageLink('isPlay') isPlay: boolean = false;
  11. songList: SongItem[] = MusicList;
  12. @Link currentBreakpoint: string;
  13. build() {
  14. Row() {
  15. Row() {
  16. Image(this.songList[this.selectIndex]?.label)
  17. .height($r('app.float.cover_height'))
  18. .width($r('app.float.cover_width'))
  19. .borderRadius($r('app.float.label_border_radius'))
  20. .margin({ right: $r('app.float.cover_margin') })
  21. .rotate({ angle: this.isPlay ? PlayerConstants.ROTATE : 0 })
  22. .animation({
  23. duration: PlayerConstants.ANIMATION_DURATION,
  24. iterations: PlayerConstants.ITERATIONS,
  25. curve: Curve.Linear
  26. })
  27. Column() {
  28. Text(this.songList[this.selectIndex].title)
  29. .fontColor($r('app.color.song_name'))
  30. .fontSize(new BreakpointType({
  31. sm: $r('app.float.song_title_sm'),
  32. md: $r('app.float.song_title_md'),
  33. lg: $r('app.float.song_title_lg')
  34. }).getValue(this.currentBreakpoint))
  35. Row() {
  36. Image($r('app.media.ic_vip'))
  37. .height($r('app.float.vip_icon_height'))
  38. .width($r('app.float.vip_icon_width'))
  39. .margin({ right: $r('app.float.vip_icon_margin') })
  40. Text(this.songList[this.selectIndex].singer)
  41. .fontColor($r('app.color.singer'))
  42. .fontSize(new BreakpointType({
  43. sm: $r('app.float.singer_title_sm'),
  44. md: $r('app.float.singer_title_md'),
  45. lg: $r('app.float.singer_title_lg')
  46. }).getValue(this.currentBreakpoint))
  47. .opacity($r('app.float.singer_opacity'))
  48. }
  49. }
  50. .alignItems(HorizontalAlign.Start)
  51. }
  52. .layoutWeight(PlayerConstants.LAYOUT_WEIGHT_PLAYER_CONTROL)
  53. Blank()
  54. Row() {
  55. Image($r('app.media.ic_previous'))
  56. .height($r('app.float.control_icon_height'))
  57. .width($r('app.float.control_icon_width'))
  58. .margin({ right: $r('app.float.control_icon_margin') })
  59. .displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO)
  60. Image(this.isPlay ? $r('app.media.ic_play') : $r('app.media.ic_pause'))
  61. .height($r('app.float.control_icon_height'))
  62. .width($r('app.float.control_icon_width'))
  63. .displayPriority(PlayerConstants.DISPLAY_PRIORITY_THREE)
  64. Image($r('app.media.ic_next'))
  65. .height($r('app.float.control_icon_height'))
  66. .width($r('app.float.control_icon_width'))
  67. .margin({
  68. right: $r('app.float.control_icon_margin'),
  69. left: $r('app.float.control_icon_margin')
  70. })
  71. .displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO)
  72. Image($r('app.media.ic_music_list'))
  73. .height($r('app.float.control_icon_height'))
  74. .width($r('app.float.control_icon_width'))
  75. .displayPriority(PlayerConstants.DISPLAY_PRIORITY_ONE)
  76. }
  77. .width(new BreakpointType({
  78. sm: $r('app.float.play_width_sm'),
  79. md: $r('app.float.play_width_sm'),
  80. lg: $r('app.float.play_width_lg')
  81. }).getValue(this.currentBreakpoint))
  82. .justifyContent(FlexAlign.End)
  83. }
  84. .width(StyleConstants.FULL_WIDTH)
  85. .height($r('app.float.player_area_height'))
  86. .backgroundColor($r('app.color.player_background'))
  87. .padding({
  88. left: $r('app.float.player_padding'),
  89. right: $r('app.float.player_padding')
  90. })
  91. .position({
  92. x: 0,
  93. y: StyleConstants.FULL_HEIGHT
  94. })
  95. .translate({
  96. x: 0,
  97. y: StyleConstants.TRANSLATE_PLAYER_Y
  98. })
  99. }
  100. }
复制

效果演示

这个是竖版效果。

cke_209.png

这个横板效果。

cke_210.png

基于自适应布局和响应式布局,实现一次开发,多端部署。

完整视频演示见:【老卫搬砖】039期:HarmonyOS ArkTS实现音乐播放器UI_哔哩哔哩_bilibili

music.gif

源码

见:GitHub - waylau/harmonyos-tutorial: HarmonyOS Tutorial. 《跟老卫学HarmonyOS开发》

学习更多HarmonyOS

作为开发者,及时投入HarmonyOS 4的学习是非常必要的。鸿蒙生态经历了艰难的四年,但轻舟已过万重山,目前已经慢慢走上了正轨,再现繁荣指日可待。

可以从HaromnyOS 官网(华为HarmonyOS智能终端操作系统官网 | 应用设备分布式开发者生态)了解到最新的HaromnyOS咨询以及开发指导。除此之外,笔者也整理了以下学习资料。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/84787
推荐阅读