From 7824cae7b73a68915f6da9659231a11d2591bb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=8B=E8=83=BD=5F=E5=BC=A0=E5=BE=B7=E7=9B=9B?= Date: Tue, 2 Sep 2025 15:49:04 +0800 Subject: [PATCH 1/3] =?UTF-8?q?README=E5=A2=9E=E5=8A=A0=E5=85=B7=E4=BD=93?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 7 +++++++ README.md | 7 +++++++ products/watch/src/main/ets/view/VolumeSliderComponent.ets | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.en.md b/README.en.md index 01a6801..e71e8fc 100644 --- a/README.en.md +++ b/README.en.md @@ -4,6 +4,7 @@ This codelab implements music album pages based on the adaptive layout and responsive layout, achieving one-time development for multi-device deployment. +## Effect Preview The figure shows the effect on the mobile phone. ![](screenshots/device/phone.en.png) @@ -72,6 +73,12 @@ The figure shows the effect on the wearable. 4. Tap the comment button on the page to go to the corresponding comment page. 5. Other buttons do not have actual tap events or functions. +## Specific Implementation +1. Use grid layout to monitor breakpoint changes and achieve differentiated display at various breakpoints. +2. Switch between areas using the Tabs component or the Swiper component. +3. Use the Blank component to achieve adaptive stretching of the middle space. +4. Smart wearable devices set borderRadius to achieve a circular watch face. + ## Permissions N/A diff --git a/README.md b/README.md index 121bc3e..a229c16 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑。 +## 效果预览 手机效果图如下: ![](screenshots/device/phone.png) @@ -71,6 +72,12 @@ 4. 点击界面上评论按钮跳转到对应的评论页面。 5. 其他按钮无实际点击事件或功能。 +## 具体实现 +1. 使用栅格布局监听断点变化,实现不同断点下的差异显示。 +2. 通过Tabs组件或Swiper组件进行区域的切换。 +3. 使用Blank组件实现中间空格自适应拉伸。 +4. 智能穿戴设备设置borderRadius实现圆形表盘 + ## 相关权限 不涉及 diff --git a/products/watch/src/main/ets/view/VolumeSliderComponent.ets b/products/watch/src/main/ets/view/VolumeSliderComponent.ets index ffd156b..351d4c6 100644 --- a/products/watch/src/main/ets/view/VolumeSliderComponent.ets +++ b/products/watch/src/main/ets/view/VolumeSliderComponent.ets @@ -67,7 +67,7 @@ export struct VolumeSlider { try { MediaService.getInstance().avPlayer?.setVolume(progress / 100); } catch (error) { - hilog.error(0x0000, 'volumeSlider', "ArcSlider setVolume failed", (error as BusinessError).code); + hilog.error(0x0000, 'volumeSlider', 'ArcSlider setVolume failed', (error as BusinessError).code); } } -- Gitee From c72ccfc154f62342a3f10ddffeba4155d4bb288e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=8B=E8=83=BD=5F=E5=BC=A0=E5=BE=B7=E7=9B=9B?= Date: Tue, 2 Sep 2025 20:31:15 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 30 ++++++++--------- README.md | 32 +++++++++---------- common/mediaCommon/src/main/module.json5 | 3 +- products/watch/src/main/ets/pages/Index.ets | 3 +- products/watch/src/main/ets/view/Home.ets | 9 ++++-- products/watch/src/main/ets/view/PlayList.ets | 6 +++- products/watch/src/main/ets/view/SongList.ets | 7 +++- .../main/ets/watchability/WatchAbility.ets | 15 +++++++++ .../watchbackupability/WatchBackupAbility.ets | 15 +++++++++ 9 files changed, 81 insertions(+), 39 deletions(-) diff --git a/README.en.md b/README.en.md index e71e8fc..53e21d3 100644 --- a/README.en.md +++ b/README.en.md @@ -48,21 +48,21 @@ The figure shows the effect on the wearable. │ │ ├──view │ │ └──viewmodel │ └──musicList/src/main/resources // Resource file directory -├──products // Product Customization Layer -│ ├──phone/src/main/ets // Supports smartphones, foldable screens, tablets, and PCs/2in1 devices -│ │ ├──common -│ │ ├──entryability -│ │ ├──pages -│ │ ├──phonebackupextability -│ │ └──viewmodel -│ ├──phone/src/main/resources // Resource file directory -│ ├──watch/src/main/ets // Support for smart wearables -│ │ ├──constants -│ │ ├──pages -│ │ ├──view -│ │ ├──watchability -│ │ └──watchbackupability -│ └──watch/src/main/resources // Resource file directory +└──products // Product Customization Layer + ├──phone/src/main/ets // Supports smartphones, foldable screens, tablets, and PCs/2in1 devices + │ ├──common + │ ├──entryability + │ ├──pages + │ ├──phonebackupextability + │ └──viewmodel + ├──phone/src/main/resources // Resource file directory + ├──watch/src/main/ets // Support for smart wearables + │ ├──constants + │ ├──pages + │ ├──view + │ ├──watchability + │ └──watchbackupability + └──watch/src/main/resources // Resource file directory ``` ## How to Use diff --git a/README.md b/README.md index a229c16..f70b5b5 100644 --- a/README.md +++ b/README.md @@ -47,21 +47,21 @@ │ │ ├──view │ │ └──viewmodel │ └──musicList/src/main/resources // 资源文件目录 -├──products // 产品定制层 -│ ├──phone/src/main/ets // 支持手机、折叠屏、平板、PC/2in1 -│ │ ├──common -│ │ ├──entryability -│ │ ├──pages -│ │ ├──phonebackupextability -│ │ └──viewmodel -│ ├──phone/src/main/resources // 资源文件目录 -│ ├──watch/src/main/ets // 支持智能穿戴 -│ │ ├──constants -│ │ ├──pages -│ │ ├──view -│ │ ├──watchability -│ │ └──watchbackupability -│ └──watch/src/main/resources // 资源文件目录 +└──products // 产品定制层 + ├──phone/src/main/ets // 支持手机、折叠屏、平板、PC/2in1 + │ ├──common + │ ├──entryability + │ ├──pages + │ ├──phonebackupextability + │ └──viewmodel + ├──phone/src/main/resources // 资源文件目录 + ├──watch/src/main/ets // 支持智能穿戴 + │ ├──constants + │ ├──pages + │ ├──view + │ ├──watchability + │ └──watchbackupability + └──watch/src/main/resources // 资源文件目录 ``` ## 使用说明 @@ -76,7 +76,7 @@ 1. 使用栅格布局监听断点变化,实现不同断点下的差异显示。 2. 通过Tabs组件或Swiper组件进行区域的切换。 3. 使用Blank组件实现中间空格自适应拉伸。 -4. 智能穿戴设备设置borderRadius实现圆形表盘 +4. 智能穿戴设备设置borderRadius实现圆形表盘。 ## 相关权限 diff --git a/common/mediaCommon/src/main/module.json5 b/common/mediaCommon/src/main/module.json5 index 9a0b309..d9506d2 100644 --- a/common/mediaCommon/src/main/module.json5 +++ b/common/mediaCommon/src/main/module.json5 @@ -5,7 +5,8 @@ "deviceTypes": [ "phone", "tablet", - "2in1" + "2in1", + "wearable" ], "requestPermissions": [ { diff --git a/products/watch/src/main/ets/pages/Index.ets b/products/watch/src/main/ets/pages/Index.ets index ce1dcf4..c6fcdaf 100644 --- a/products/watch/src/main/ets/pages/Index.ets +++ b/products/watch/src/main/ets/pages/Index.ets @@ -15,7 +15,7 @@ import { ArcSwiper, - ArcSwiperAttribute, + ArcSwiperAttribute, // The properties of ArcSwiper depend on the ArcSwiperAttribute object for import. ArcDotIndicator, ArcDirection, ArcSwiperController @@ -26,7 +26,6 @@ import { MediaService } from '@ohos/mediaCommon'; import { songList } from 'musicList'; import { StyleConstants } from '../constants/StyleConstants'; -@Preview @Entry @Component struct Index { diff --git a/products/watch/src/main/ets/view/Home.ets b/products/watch/src/main/ets/view/Home.ets index 200e7dd..b6c91f2 100644 --- a/products/watch/src/main/ets/view/Home.ets +++ b/products/watch/src/main/ets/view/Home.ets @@ -14,7 +14,11 @@ */ import { LengthMetrics } from '@kit.ArkUI'; -import { ArcList, ArcListItem, ArcListAttribute } from '@kit.ArkUI'; +import { + ArcList, + ArcListItem, + ArcListAttribute // The properties of ArcList depend on the ArcListAttribute object for import. +} from '@kit.ArkUI'; import { StyleConstants } from '../constants/StyleConstants'; class Menu { @@ -90,8 +94,7 @@ export struct Home { this.pageStack.replacePathByName(item.pathName, null); }) } - }, - (item: Menu, index: number) => JSON.stringify(item) + index) + }, (item: Menu, index: number) => JSON.stringify(item) + index) } .scrollBar(BarState.Off) .space(LengthMetrics.vp(5)) diff --git a/products/watch/src/main/ets/view/PlayList.ets b/products/watch/src/main/ets/view/PlayList.ets index 37ba7a5..dd6893f 100644 --- a/products/watch/src/main/ets/view/PlayList.ets +++ b/products/watch/src/main/ets/view/PlayList.ets @@ -13,7 +13,11 @@ * limitations under the License. */ -import { ArcSwiper, ArcSwiperAttribute, ArcSwiperController } from '@kit.ArkUI'; +import { + ArcSwiper, + ArcSwiperAttribute, // The properties of ArcSwiper depend on the ArcSwiperAttribute object for import. + ArcSwiperController +} from '@kit.ArkUI'; import { StyleConstants } from '../constants/StyleConstants'; @Builder diff --git a/products/watch/src/main/ets/view/SongList.ets b/products/watch/src/main/ets/view/SongList.ets index f4fc1b6..aba815f 100644 --- a/products/watch/src/main/ets/view/SongList.ets +++ b/products/watch/src/main/ets/view/SongList.ets @@ -14,7 +14,12 @@ */ import { LengthMetrics } from '@kit.ArkUI'; -import { ArcList, ArcListItem, ArcListAttribute, ArcListItemAttribute } from '@kit.ArkUI'; +import { + ArcList, + ArcListItem, + ArcListAttribute, // The properties of ArcList depend on ArcListAttribute and ArcListItemAttribute objects for import. + ArcListItemAttribute +} from '@kit.ArkUI'; import { MediaService, SongItem } from '@ohos/mediaCommon'; import { StyleConstants } from '../constants/StyleConstants'; diff --git a/products/watch/src/main/ets/watchability/WatchAbility.ets b/products/watch/src/main/ets/watchability/WatchAbility.ets index efa9a31..c9e33b7 100644 --- a/products/watch/src/main/ets/watchability/WatchAbility.ets +++ b/products/watch/src/main/ets/watchability/WatchAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; diff --git a/products/watch/src/main/ets/watchbackupability/WatchBackupAbility.ets b/products/watch/src/main/ets/watchbackupability/WatchBackupAbility.ets index d5e190e..2a9f646 100644 --- a/products/watch/src/main/ets/watchbackupability/WatchBackupAbility.ets +++ b/products/watch/src/main/ets/watchbackupability/WatchBackupAbility.ets @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; -- Gitee From 378f3424dbbb90d2c60b0442cf598d674ecc0eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=8B=E8=83=BD=5F=E5=BC=A0=E5=BE=B7=E7=9B=9B?= Date: Wed, 3 Sep 2025 18:37:19 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- products/watch/src/main/ets/pages/Index.ets | 6 ++++++ products/watch/src/main/ets/view/Home.ets | 6 ++++++ products/watch/src/main/ets/view/PlayList.ets | 9 +++++++++ products/watch/src/main/ets/view/SongList.ets | 8 +++++++- products/watch/src/main/ets/view/SongPage.ets | 13 ++++++++++++- .../src/main/ets/view/VolumeSliderComponent.ets | 3 +++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/products/watch/src/main/ets/pages/Index.ets b/products/watch/src/main/ets/pages/Index.ets index c6fcdaf..295e77c 100644 --- a/products/watch/src/main/ets/pages/Index.ets +++ b/products/watch/src/main/ets/pages/Index.ets @@ -41,6 +41,7 @@ struct Index { build() { Navigation(this.pageStack) { + // [Start home_swiper] Column() { Row() { ArcSwiper(this.wearableSwiperController) { @@ -52,6 +53,7 @@ struct Index { .arcDirection(ArcDirection.SIX_CLOCK_DIRECTION) .selectedItemColor('#FE1B48') ) + // [StartExclude home_swiper] .onAnimationStart((index: number, targetIndex: number) => { this.innerSelectedIndex = targetIndex; }) @@ -73,10 +75,14 @@ struct Index { } return GestureJudgeResult.CONTINUE; }) + + // [EndExclude home_swiper] } .height(StyleConstants.FULL_HEIGHT) } .width(StyleConstants.FULL_WIDTH) + + // [End home_swiper] } .hideTitleBar(true) } diff --git a/products/watch/src/main/ets/view/Home.ets b/products/watch/src/main/ets/view/Home.ets index b6c91f2..42309b0 100644 --- a/products/watch/src/main/ets/view/Home.ets +++ b/products/watch/src/main/ets/view/Home.ets @@ -62,6 +62,7 @@ export struct Home { ]; build() { + // [Start home_list] Column() { ArcList({ initialIndex: 0 }) { ForEach(this.menuList, (item: Menu) => { @@ -87,12 +88,15 @@ export struct Home { .justifyContent(FlexAlign.SpaceBetween) .borderRadius(StyleConstants.CIRCLE_BORDER_RADIUS) .backgroundColor($r('app.color.home_btn_background')) + // [StartExclude home_list] .onClick(() => { if (item.pathName === 'setting') { return; } this.pageStack.replacePathByName(item.pathName, null); }) + + // [EndExclude home_list] } }, (item: Menu, index: number) => JSON.stringify(item) + index) } @@ -107,5 +111,7 @@ export struct Home { .width(StyleConstants.FULL_WIDTH) .height(StyleConstants.FULL_HEIGHT) .borderRadius(StyleConstants.CIRCLE_BORDER_RADIUS) + + // [End home_list] } } \ No newline at end of file diff --git a/products/watch/src/main/ets/view/PlayList.ets b/products/watch/src/main/ets/view/PlayList.ets index dd6893f..db5b87e 100644 --- a/products/watch/src/main/ets/view/PlayList.ets +++ b/products/watch/src/main/ets/view/PlayList.ets @@ -60,6 +60,7 @@ export struct PlayList { build() { NavDestination() { + // [Start play_list] Column() { ArcSwiper(this.wearableSwiperController) { ForEach(this.playList, (item: PlayListSheet) => { @@ -86,9 +87,12 @@ export struct PlayList { .backgroundImageSize({ width: StyleConstants.FULL_WIDTH, height: StyleConstants.FULL_HEIGHT }) .justifyContent(FlexAlign.SpaceBetween) .padding({ top: $r('app.float.playlist_row_padding'), bottom: $r('app.float.playlist_row_padding') }) + // [StartExclude play_list] .onClick(() => { this.pageStack.replacePathByName('songList', null); }) + + // [EndExclude play_list] }, (item: PlayListSheet, index?: number) => index + JSON.stringify(item)) } .index(0) @@ -98,6 +102,7 @@ export struct PlayList { .defaultFocus(true) .vertical(true) .indicator(false) + // [StartExclude play_list] .disableSwipe(false) .digitalCrownSensitivity(CrownSensitivity.MEDIUM) .disableTransitionAnimation(false) @@ -122,9 +127,13 @@ export struct PlayList { } return GestureJudgeResult.CONTINUE; }) + + // [EndExclude play_list] } .width(StyleConstants.FULL_WIDTH) .height(StyleConstants.FULL_HEIGHT) + + // [End play_list] } .hideTitleBar(true) } diff --git a/products/watch/src/main/ets/view/SongList.ets b/products/watch/src/main/ets/view/SongList.ets index aba815f..46d52a0 100644 --- a/products/watch/src/main/ets/view/SongList.ets +++ b/products/watch/src/main/ets/view/SongList.ets @@ -41,9 +41,10 @@ struct SongList { build() { NavDestination() { + // [Start song_list] Column() { ArcList({ initialIndex: 0 }) { - ForEach(this.songList, (item: SongItem, index:number) => { + ForEach(this.songList, (item: SongItem, index: number) => { ArcListItem() { Row() { Image(item.label) @@ -69,10 +70,13 @@ struct SongList { .backgroundColor($r('app.color.home_btn_background')) } .align(Alignment.Center) + // [StartExclude song_list] .onClick(async () => { await MediaService.getInstance().loadAssent(index); this.pageStack.replacePathByName('songPage', null); }) + + // [EndExclude song_list] }, (item: SongItem, index: number) => JSON.stringify(item) + index) } .scrollBar(BarState.Off) @@ -86,6 +90,8 @@ struct SongList { .width(StyleConstants.FULL_WIDTH) .height(StyleConstants.FULL_HEIGHT) .borderRadius(StyleConstants.CIRCLE_BORDER_RADIUS) + + // [End song_list] } .hideTitleBar(true) } diff --git a/products/watch/src/main/ets/view/SongPage.ets b/products/watch/src/main/ets/view/SongPage.ets index 8e1638d..cec3f63 100644 --- a/products/watch/src/main/ets/view/SongPage.ets +++ b/products/watch/src/main/ets/view/SongPage.ets @@ -42,6 +42,7 @@ struct SongPage { build() { NavDestination() { + // [Start song_page] Column() { Column() { Text(this.songList[this.selectIndex].title) @@ -56,10 +57,12 @@ struct SongPage { Image($r('app.media.previous_btn')) .width($r('app.float.play_song_img')) } + // [StartExclude song_page] .onClick(() => { MediaService.getInstance().playPrevious(); }) + // [EndExclude song_page] Stack() { Image(this.songList[this.selectIndex].label) .width($r('app.float.play_circle_img')) @@ -74,20 +77,24 @@ struct SongPage { Image($r('app.media.play_btn')) .width($r('app.float.play_song_img')) .visibility(this.isPlay === true ? Visibility.None : Visibility.Visible) + // [StartExclude song_page] .onClick(() => { if (MediaService.getInstance().getFirst()) { MediaService.getInstance().loadAssent(0); } else { - this.isPlay ? MediaService.getInstance().pause() : MediaService.getInstance().play(); + this.isPlay ? MediaService.getInstance().pause() : MediaService.getInstance().play(); } }) + // [EndExclude song_page] Image($r('app.media.pause_btn')) .width($r('app.float.play_song_img')) .visibility(this.isPlay === true ? Visibility.Visible : Visibility.None) + // [StartExclude song_page] .onClick(() => { MediaService.getInstance().pause(); }) + // [EndExclude song_page] } .width(this.HALF_WIDTH) .align(Alignment.Center) @@ -96,9 +103,12 @@ struct SongPage { Image($r('app.media.next_btn')) .width($r('app.float.play_song_img')) } + // [StartExclude song_page] .onClick(() => { MediaService.getInstance().playNextAuto(true); }) + + // [EndExclude song_page] } .justifyContent(FlexAlign.SpaceAround) .width('85%') @@ -119,6 +129,7 @@ struct SongPage { .padding({ top: $r('app.float.play_column_padding'), bottom: $r('app.float.play_column_padding') }) .justifyContent(FlexAlign.SpaceAround) + // [End song_page] VolumeSlider() } .hideTitleBar(true) diff --git a/products/watch/src/main/ets/view/VolumeSliderComponent.ets b/products/watch/src/main/ets/view/VolumeSliderComponent.ets index 351d4c6..1ceb26e 100644 --- a/products/watch/src/main/ets/view/VolumeSliderComponent.ets +++ b/products/watch/src/main/ets/view/VolumeSliderComponent.ets @@ -72,6 +72,7 @@ export struct VolumeSlider { } build() { + // [Start volume_slider] Column() { ArcSlider({ options: this.arcSliderOptions }) .focusable(true) @@ -99,5 +100,7 @@ export struct VolumeSlider { top: 0, right: 0 }) + + // [End volume_slider] } } -- Gitee