diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..bd2d4c75fa35c3c68684988eab0c2cd069d623fd --- /dev/null +++ b/README.en.md @@ -0,0 +1,79 @@ +# Dark Mode + +### Overview +This sample describes dark mode adaptation, helping you adapt color resources, media resources, and status bar and ensure +that the app UI is beautiful and natural when the system switches between the dark and light modes. The app also provides +a user-controllable dark/light mode switch to meet users' personalized requirements and to implement dark/light mode switching +in different scenarios. + + +### Preview + +| Light mode | Dark Mode | +|:---------------------------------:|:--------------------------------:| +| ![home](screenshots/light_en.png) | ![util](screenshots/dark_en.png) | + +How to Use + +1. The color mode of the app is in sync with the system color mode (dark/light) by default. This function can be enabled + or disabled by choosing Settings > Display & brightness > Dark mode > Enable all day. + +2. You can disable the function of switching the color mode in sync with the system by choosing Me > Dark mode in the app. + Then, the app will always be in light mode. + +3. You can manually enable or disable the dark mode by choosing Me > Dark mode in the app. The app will display the dark + or light mode based on the settings. + +### Project Directory + +``` +├──entry/src/main/ets/ +│ ├──entryability +│ │ └──EntryAbility.ets // Entry ability +│ ├──pages +│ │ ├──DarkModeSetting.ets // Page for setting the dark mode +│ │ ├──Home.ets // Home page +│ │ ├──Index.ets // App entry +│ │ └──Mine.ets // Me page +│ ├──view +│ │ ├──FinishedTodoItem.ets // Finished Todo component +│ │ └──TodoItem.ets // Todo component +│ └──viewmodel +│ ├──ColorModeChangeFunctions.ets // Function for switching between the dark and light modes +│ ├──Todo.ets // Todo class +│ └──TodoViewModel.ets // Todo data +└──entry/src/main/resources // Static resources of the app +``` + +### Required Permissions +1. Adapt color resources, such as the text color and component background color. The following two solutions are available: + +2. Use the color resource values reserved by the system. + +3. Perform manual adaptation: Create the src/main/resources/dark/element directory, create the color.json file in the + directory, set the color values of page elements in dark mode in the file, and set the color values of page elements + in light mode in the src/main/resources/base/element/color.json file. + +4. Adapt images and icons. If you want your app to display different images/icons in dark and light modes, create the + src/main/resources/dark/media directory to store the images and icons in dark mode, and place different static resources + with the same name in src/main/resources/base/media. + +5. Adapt the system status bar. By default, if the immersive mode is not enabled for the app, there will be no problem for + status bar adaptation. If the immersive mode is enabled for the app, the contrast between the background color of the + page and the text color of the status bar may be too low. As a result, the text on the status bar is invisible to users, + affecting user experience. In this case, you can set the text color of the status bar dynamically through setWindowSystemBarProperties + by listening for the dark and light mode changes of the system. + +### Required Permissions + +- N/A + +### Constraints + +1. The sample is only supported on Huawei phones with standard systems. + +2. The HarmonyOS version must be HarmonyOS 5.0.0 Release or later. + +3. The DevEco Studio version must be DevEco Studio 5.0.0 Release or later. + +4. The HarmonyOS SDK version must be HarmonyOS 5.0.0 Release SDK or later. diff --git a/README.md b/README.md index e5b8f5f2258310c432660fdb0978860a3fea866f..d50a348e7bdb8fac41fdd5e350c39ffe1de46a5f 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,49 @@ -# 实现深色模式功能 +# 深色模式 ### 简介 -本示例采用深色模式适配相关技术,确保应用在系统深浅色模式切换时界面效果美观自然,实现颜色资源适配、媒体资源适配、状态栏适配等。应用内还提供用户可控的深浅色模式开关,满足用户个性化需求,实现应用在不同模式下的深浅色切换。 +本示例通过@ohos.app.ability.ConfigurationConstant等接口,进行深色模式的设置。 ### 效果预览: -![](./screenshots/phone.gif) + +| **浅色模式** | **深色模式** | +|:------------------------------:|:-----------------------------:| +| ![home](screenshots/light.png) | ![util](screenshots/dark.png) | + +使用说明: + +1.启动应用后,首页根据系统深浅模式设定进行显示; + +2.在后台系统设置-深色模式中切换; + +3.返回应用,首页根据系统深浅模式设定进行显示; ### 工程目录 ``` ├──entry/src/main/ets/ +│ ├──common +│ │ └──Constants.ets // 公共常量类 │ ├──entryability -│ │ └──EntryAbility.ets // 程序入口 -│ ├──pages -│ │ ├──DarkModeSetting.ets // 深色模式设置页面 -│ │ ├──Home.ets // 主页 -│ │ ├──Index.ets // 程序页面入口 -│ │ └──Mine.ets // 我的页面 +│ │ └──EntryAbility.ets // 程序入口类 +│ ├──pages +│ │ └──Index.ets // 首页 │ ├──view -│ │ ├──FinishedTodoItem.ets // 已完成的Todo组件 -│ │ └──TodoItem.ets // Todo组件 +│ │ └──GoodsList.ets // 购物列表组件 │ └──viewmodel -│ ├──ColorModeChangeFunctions.ets // 深浅模式切换功能函数封装 -│ ├──Todo.ets // Todo类 -│ └──TodoViewModel.ets // Todo数据 +│ └──GoodsModel.ets // 购物项类 └──entry/src/main/resources // 应用静态资源目录 ``` -使用说明: -- 默认应用跟随系统深浅色进行切换,在设置->显示与亮度->深色模式->全天开启中进行打开关闭,应用会跟随进行深浅色显示。 -- 应用内提供关闭跟随系统切换功能,在我的->深色模式中关闭跟随系统设置,应用将始终保持浅色模式。 -- 应用内提供手动控制深浅色开关,在我的->深色模式中打开/关闭深色模式,应用会跟随设置的值选择深色/浅色显示。 - -### 具体实现 - -1. 颜色资源适配例如文本颜色,组件背景颜色等。有以下两种方案: - 1. 使用系统预留的颜色资源值。 - 2. 开发者进行手动适配。需要开发者创建src/main/resources/dark/element目录,并在目录下创建color.json文件,在文件中设置页面元素在深色模式下的颜色值,并在src/main/resources/base/element/color.json文件中设置浅色模式下的页面元素颜色值。 -2. 图片与图标资源适配。若需要应用在深色模式与浅色模式下呈现不同的图片/图标,需要开发者创建出src/main/resources/dark/media目录,用于放置应用在深色模式下的图片与图标资源,并在src/main/resources/base/media放入同名但不同的静态资源。 -3. 系统状态栏适配。默认情况下若应用未启用沉浸式,则不会存在状态栏适配问题,若应用设置了沉浸式,可能会导致页面的背景色与状态栏文字颜色对比度过低,对用户而言状态栏文字不可见,影响用户体验,此种情况下,可以考虑监听系统深浅色模式变化动态地通过setWindowSystemBarProperties来设置状态栏文字颜色。 ### 相关权限 -不涉及 +- 无权限涉及 ### 约束与限制 1.本示例仅支持标准系统上运行,支持设备:华为手机。 -2.HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 +2.HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。 -3.DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 +3.DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。 -4.HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。 \ No newline at end of file +4.HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。 \ No newline at end of file diff --git a/entry/src/main/ets/common/Constants.ets b/entry/src/main/ets/common/Constants.ets new file mode 100644 index 0000000000000000000000000000000000000000..11baa158303dcbe4bcb86ee9bfc8c6e168802b72 --- /dev/null +++ b/entry/src/main/ets/common/Constants.ets @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 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 { ProductDataModel } from '../viewmodel/GoodsModel'; + +export class Constants { + /** + * Offering List Data Source. + */ + static readonly PRODUCT_DATA: Array = [ + new ProductDataModel(0, $r('app.media.product00'), $r('app.string.product_title00'), $r('app.string.product_price00'), $r('app.string.product_view00')), + new ProductDataModel(1, $r('app.media.product01'), $r('app.string.product_title01'), $r('app.string.product_price01'), $r('app.string.product_view01')), + new ProductDataModel(2, $r('app.media.product02'), $r('app.string.product_title02'), $r('app.string.product_price02'), $r('app.string.product_view02')), + new ProductDataModel(3, $r('app.media.product04'), $r('app.string.product_title04'), $r('app.string.product_price04'), $r('app.string.product_view04')), + new ProductDataModel(4, $r('app.media.product05'), $r('app.string.product_title05'), $r('app.string.product_price05'), $r('app.string.product_view05')) + ]; + /** + * Interval space. + */ + static readonly COLUM_SPACE:number = 10; + /** + * Dark mode colors. + */ + static readonly DARK_MODE_COLORS:string = '#000000'; + /** + * Light mode colors. + */ + static readonly LIGHT_MODE_COLORS:string = '#FFFFFF'; + /** + * Normal mode colors. + */ + static readonly NORMAL_MODE_COLORS:string = '#FA5a3C'; + /** + * Gutter X. + */ + static readonly GUTTER_X:number = 8; + /** + * Gutter Y. + */ + static readonly GUTTER_Y:number = 8; + /** + * offset. + */ + static readonly OFFSET:number = -3; + /** + * Image aspect ratio. + */ + static readonly IMAGE_ASPECT_RATIO:number = 1; + /** + * Grid col span. + */ + static readonly GRID_COL_SPAN:number = 6; + /** + * One hundred percent. + */ + static readonly FULL_PERCENT:string = '100%'; + +} \ No newline at end of file diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/entry/src/main/ets/entryability/EntryAbility.ets index 99c7b9225b8c8908af3a596fa255fc3d2678d674..0d93aa0999fa518489a97bed36f17149777b91e2 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/entry/src/main/ets/entryability/EntryAbility.ets @@ -12,14 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { window } from '@kit.ArkUI'; +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; -import { AbilityConstant, Configuration, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode); hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } @@ -28,7 +26,8 @@ export default class EntryAbility extends UIAbility { } onWindowStageCreate(windowStage: window.WindowStage): void { - // Main window is created, set main page for this ability + AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode); + AppStorage.setOrCreate('windowStage', windowStage); hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err) => { @@ -37,14 +36,6 @@ export default class EntryAbility extends UIAbility { return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); - const windowClass = windowStage.getMainWindowSync(); - windowClass.setWindowLayoutFullScreen(true); - const avoidAreaTop = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - const avoidAreaBottom = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); - const topRectHeight = avoidAreaTop.topRect.height; - const bottomRectHeight = avoidAreaBottom.bottomRect.height; - AppStorage.setOrCreate('topRectHeight', px2vp(topRectHeight)); - AppStorage.setOrCreate('bottomRectHeight', px2vp(bottomRectHeight)); }); } @@ -55,6 +46,7 @@ export default class EntryAbility extends UIAbility { onForeground(): void { // Ability has brought to foreground + AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode); hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } @@ -62,11 +54,4 @@ export default class EntryAbility extends UIAbility { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } - - onConfigurationUpdate(newConfig: Configuration): void { - const currentColorMode: ConfigurationConstant.ColorMode | undefined = AppStorage.get('currentColorMode'); - if (currentColorMode !== newConfig.colorMode) { - AppStorage.setOrCreate('currentColorMode', newConfig.colorMode); - } - } } diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index bd28ec565f78d67b5a4eea528665bcaa226b10b1..66d44e0a0957cef98622475e7c6455dc9e54212c 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -12,99 +12,160 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { GoodsList } from '../view/GoodsList'; +import { ConfigurationConstant } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; +import { promptAction } from '@kit.ArkUI'; +import { Constants } from '../common/Constants'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { i18n } from '@kit.LocalizationKit'; -import { DarkModeSetting } from './DarkModeSetting'; -import { Home } from './Home'; -import { Mine } from './Mine'; +const IMAGE_ASPECT_RATIO: number = 1; +const LAYOUT_WEIGHT: number = 1; @Entry -@Component -struct Index { - @State currentIndex: number = 0; - @Provide navPathStack: NavPathStack = new NavPathStack(); - @StorageProp('topRectHeight') topRectHeight: number = 0; - @StorageProp('bottomRectHeight') bottomRectHeight: number = 0; - private tabsController: TabsController = new TabsController(); - - @Builder - tabBuilder(title: ResourceStr, unSelectIcon: Resource, selectedIcon: Resource, targetIndex: number) { - Column() { - SymbolGlyph(this.currentIndex === targetIndex ? selectedIcon : unSelectIcon) - .fontSize(24) - .fontColor(this.currentIndex === targetIndex ? - [$r('sys.color.icon_emphasize')] : - [$r('sys.color.icon_secondary')] - ) - .symbolEffect(new BounceSymbolEffect(EffectScope.WHOLE, EffectDirection.UP), this.currentIndex === targetIndex) - .margin({ bottom: 4 }) - Text(title) - .fontSize(10) - .fontWeight(500) - .lineHeight(13) - .fontColor(this.currentIndex === targetIndex ? - $r('sys.color.icon_emphasize') : - $r('sys.color.icon_secondary') - ) - } - .width('100%') - .height(52 + this.bottomRectHeight) - .padding({ top: 5 }) - .justifyContent(FlexAlign.Start) - .onClick(() => { - this.currentIndex = targetIndex; - this.tabsController.changeIndex(targetIndex); - }) +export struct Index { + @State banner: Resource = $r('app.media.light_mode_banner'); + @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number = 0; + + onColorModeChange(): void { + this.banner = setBanner(this.currentMode); } - @Builder - PageMap(name: string) { - if ('darkModeSetting' === name) { - DarkModeSetting() - } + aboutToAppear(): void { + this.banner = setBanner(this.currentMode); + } + + aboutToDisappear(): void { + setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); } build() { - Navigation(this.navPathStack) { - Tabs({ controller: this.tabsController }) { - TabContent() { - Home() + Column() { + Column({ space: Constants.COLUM_SPACE }) { + + Flex({ justifyContent: FlexAlign.SpaceBetween }) { + Image($r('app.media.logo')) + .width($r('app.float.image_width')) + .aspectRatio(IMAGE_ASPECT_RATIO) + + Image($r('app.media.scan')) + .width($r('app.float.image_width')) + .aspectRatio(IMAGE_ASPECT_RATIO) + .onClick(() => { + promptAction.showToast({ message: $r('app.string.mode_other_function') }); + }) } - .tabBar(this.tabBuilder( - $r('app.string.home'), - $r('sys.symbol.house'), - $r('sys.symbol.house_fill'), - 0 - )) - - TabContent() { + .width(Constants.FULL_PERCENT) + .height($r('app.float.flex_height')) + .margin({ top: $r('app.float.flex_margin_top') }) + + Row() { + Image($r('app.media.search')) + .width($r('app.float.search_image_width')) + .aspectRatio(IMAGE_ASPECT_RATIO) + .margin({ left: $r('app.float.search_image_margin_left') }) + Text($r('app.string.search_text')) + .opacity($r('app.float.font_opacity')) + .fontColor($r('app.color.black_font_color')) + .margin({ left: $r('app.float.text_margin_left') }) } - .tabBar(this.tabBuilder( - $r('app.string.discover'), - $r('sys.symbol.fast'), - $r('sys.symbol.fast_fill'), - 1 - )) - - TabContent() { - Mine() + .width(Constants.FULL_PERCENT) + .height($r('app.float.row_height')) + .backgroundColor($r('app.color.search_bg_color')) + .borderRadius($r('app.float.row_border_radius')) + .onClick(() => { + promptAction.showToast({ message: $r('app.string.mode_other_function') }); + }) + + } + .padding({ left: $r('app.float.column_padding'), right: $r('app.float.column_padding') }) + .backgroundColor($r('app.color.column_bg_color')) + .width(Constants.FULL_PERCENT) + .height($r('app.float.column_height')) + + Scroll() { + Column() { + Column() { + Image(this.banner) + .width(Constants.FULL_PERCENT) + .height($r('app.float.banner_height')) + .borderRadius($r('app.float.banner_border_radius')) + + Text($r('app.string.new_product_text')) + .fontColor($r('app.color.white_font_color')) + .fontSize($r('app.float.new_goods_font')) + .fontWeight(FontWeight.Bold) + .height($r('app.float.new_goods_height')) + .width(Constants.FULL_PERCENT) + .textAlign(TextAlign.Center) + .padding({ top: $r('app.float.new_goods_padding_top') }) + } + .backgroundColor($r('app.color.column_bg_color')) + .padding({ left: $r('app.float.column_padding'), right: $r('app.float.column_padding') }) + .borderRadius({ + bottomLeft: $r('app.float.column_border_radius'), + bottomRight: $r('app.float.column_border_radius') + }) + + GoodsList() } - .tabBar(this.tabBuilder( - $r('app.string.mine'), - $r('sys.symbol.person'), - $r('sys.symbol.person_fill'), - 2 - )) } - .barPosition(BarPosition.End) - .scrollable(false) - .barHeight(52 + this.bottomRectHeight) - .barOverlap(true) - .barBackgroundColor('#1AE6E6E6') - .barBackgroundBlurStyle(BlurStyle.COMPONENT_THICK) + .backgroundColor($r("app.color.list_bg_color")) + .padding({ bottom: $r('app.float.column_padding_bottom') }) + .width(Constants.FULL_PERCENT) + .height(Constants.FULL_PERCENT) + .layoutWeight(LAYOUT_WEIGHT) + .scrollBar(BarState.Off) + .align(Alignment.Top) } - .backgroundColor($r('app.color.app_background_color')) - .hideTitleBar(true) - .navDestination(this.PageMap) - .padding({ top: this.topRectHeight }) + .backgroundColor($r('app.color.page_bg_color')) + .width(Constants.FULL_PERCENT) + .height(Constants.FULL_PERCENT) } -} \ No newline at end of file +} + +function setBanner(currentMode: number): Resource { + if (currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) { + setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_DARK); + if (i18n.System.getSystemLanguage() == 'zh-Hans') { + return $r("app.media.dark_mode_banner"); + } else { + return $r("app.media.dark_mode_banner_en"); + } + } else { + setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + if (i18n.System.getSystemLanguage() == 'zh-Hans') { + return $r("app.media.light_mode_banner"); + } else { + return $r("app.media.light_mode_banner_en"); + } + } +} + +async function setStatusBar(currentMode: number) { + const windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage; + windowStage.getMainWindow((err, data) => { + hilog.error(0x0000, 'testTag', 'Failed', JSON.stringify(err) ?? ''); + let color = ''; + let fontColor = '' + if (currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) { + color = Constants.DARK_MODE_COLORS; + fontColor = Constants.LIGHT_MODE_COLORS; + } else if (currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT) { + color = Constants.LIGHT_MODE_COLORS; + fontColor = Constants.DARK_MODE_COLORS; + } else { + color = Constants.NORMAL_MODE_COLORS; + fontColor = Constants.LIGHT_MODE_COLORS; + } + const sysBarProps: window.SystemBarProperties = { + statusBarColor: color, + statusBarContentColor:fontColor + }; + + data.setWindowSystemBarProperties(sysBarProps, (err) => { + hilog.error(0x0000, 'testTag', 'Failed', JSON.stringify(err) ?? ''); + }); + }) +} diff --git a/entry/src/main/ets/view/GoodsList.ets b/entry/src/main/ets/view/GoodsList.ets new file mode 100644 index 0000000000000000000000000000000000000000..e3a4c6556bbf4ddaba0bbe9cd993ec9542475f72 --- /dev/null +++ b/entry/src/main/ets/view/GoodsList.ets @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 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 { Constants } from '../common/Constants'; +import { ProductDataModel } from '../viewmodel/GoodsModel'; +import { promptAction } from '@kit.ArkUI'; + +@Component +export struct GoodsList { + build() { + GridRow({ gutter: { x: Constants.GUTTER_X, y: Constants.GUTTER_Y }, }) { + ForEach(Constants.PRODUCT_DATA, (item: ProductDataModel) => { + GridCol({ span: Constants.GRID_COL_SPAN }) { + ItemView({ item: item }) + } + }, (item: ProductDataModel) => item.id.toString()) + } + .padding($r('app.float.grid_row_padding')) + .backgroundColor($r("app.color.list_bg_color")) + } +} + +@Component +struct ItemView { + @Prop item: ProductDataModel; + + build() { + Column() { + Image(this.item.uri) + .width('70%') + .aspectRatio(Constants.IMAGE_ASPECT_RATIO) + .objectFit(ImageFit.Contain) + .margin({ bottom: $r('app.float.goods_image_margin_bottom') }) + + Column() { + Text(this.item.title) + .width(Constants.FULL_PERCENT) + .fontSize($r('app.float.goods_font')) + .fontColor($r('sys.color.ohos_id_color_foreground')) + Flex({ justifyContent: FlexAlign.SpaceBetween }) { + Text(this.item.price) + .fontSize($r('app.float.goods_font')) + .offset({ x: Constants.OFFSET }) + .fontColor($r('sys.color.ohos_id_color_foreground')) + Row() { + Image($r('app.media.view')) + .fillColor($r('app.color.view_fill_color')) + .width($r('app.float.view_image_width')) + .aspectRatio(Constants.IMAGE_ASPECT_RATIO) + .objectFit(ImageFit.Contain) + + Text(this.item.views) + .fontSize($r('app.float.view_font')) + .margin({ left: $r('app.float.view_margin_left') }) + .fontColor($r('sys.color.ohos_id_color_foreground')) + } + .alignItems(VerticalAlign.Center) + } + .margin({ top: $r('app.float.flex_margin_top') }) + } + .margin({ left: $r('app.float.goods_column_padding_left') }) + .alignItems(HorizontalAlign.Start) + } + .onClick(() => { + promptAction.showToast({ message: $r('app.string.mode_other_function') }); + }) + .borderRadius($r('app.float.goods_border_radius')) + .padding($r('app.float.column_padding')) + .backgroundColor($r("app.color.product_bg_color")) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/viewmodel/GoodsModel.ets b/entry/src/main/ets/viewmodel/GoodsModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..17b8e90d093c51f3b4bde73525b39751975365ea --- /dev/null +++ b/entry/src/main/ets/viewmodel/GoodsModel.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 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. + */ + +export class ProductDataModel { + id: number; + uri: ResourceStr; + title: ResourceStr; + price: ResourceStr; + views: ResourceStr; + + constructor(id: number, uri: ResourceStr, title: ResourceStr, price: ResourceStr, views: ResourceStr) { + this.id = id; + this.uri = uri; + this.title = title; + this.price = price; + this.views = views; + } +} \ No newline at end of file diff --git a/entry/src/main/module.json5 b/entry/src/main/module.json5 index 5f6f8e183e9195d8178183502bf018e80c02f9a1..de78b5cae3b2ba99788048311e5d0cd34d075039 100644 --- a/entry/src/main/module.json5 +++ b/entry/src/main/module.json5 @@ -5,7 +5,9 @@ "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ - "phone" + "phone", + "tablet", + "2in1" ], "deliveryWithInstall": true, "installationFree": false, diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json index 46df7c5b2653fe0cfe89a543ec92e3ac54105343..75873f03e6c06baab620fd6f61fa500c7423f144 100644 --- a/entry/src/main/resources/base/element/color.json +++ b/entry/src/main/resources/base/element/color.json @@ -5,64 +5,40 @@ "value": "#FFFFFF" }, { - "name": "app_background_color", - "value": "#F1F3F5" - }, - { - "name": "sub_title_color", - "value": "#E6000000" - }, - { - "name": "sub_title_date", - "value": "#66000000" - }, - { - "name": "font_color", - "value": "#E6000000" - }, - { - "name": "item_box", + "name": "page_bg_color", "value": "#FFFFFF" }, { - "name": "todo_date", - "value": "#66000000" + "name": "column_bg_color", + "value": "#FA5A3C" }, { - "name": "todo_time", - "value": "#66000000" + "name": "black_font_color", + "value": "#000000" }, { - "name": "sub_text_color", - "value": "#99000000" - }, - { - "name": "bell_color", - "value": "#E6FFFFFF" - }, - { - "name": "horizon_box", - "value": "#33000000" + "name": "white_font_color", + "value": "#FFFFFF" }, { - "name": "arrow_color", - "value": "#767676" + "name": "search_bg_color", + "value": "#FFFFFF" }, { - "name": "icon_bg_color", - "value": "#E6E8E9" + "name": "product_bg_color", + "value": "#FFFFFF" }, { - "name": "left_icon_color", - "value": "#A1A2A3" + "name": "list_bg_color", + "value": "#E7D9D9" }, { - "name": "right_icon_color", - "value": "#171717" + "name": "custom_bg_color", + "value": "#FFFFFF" }, { - "name": "tab_bar_background_color", - "value": "#40F1F3F5" + "name": "view_fill_color", + "value": "#000000" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index 47146b406ccaa97f91bab0a3fe3c4a7e6b885d4b..a2d600f7a5c4696a2610f163505a4dca2a63aa45 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -13,96 +13,124 @@ "value": "FitForDarkMode" }, { - "name": "today_plan", - "value": "Sprint review for IELTS exam, Chapter 3, comprehensive review" + "name": "fixed_color_value", + "value": "直接设置固定色值" }, { - "name": "end", - "value": "End" + "name": "resource_color_value", + "value": "用资源方式设置色值" }, { - "name": "already_reported", - "value": "Time already reported" + "name": "system_color_value", + "value": "用系统方式设置色值" }, { - "name": "please_input_account", - "value": "Please enter your account" + "name": "png_format_image", + "value": "Png格式图片(WEBG/JEPG)" }, { - "name": "please_input_password", - "value": "Please enter your password" + "name": "svg_format_image", + "value": "SVG格式图片" }, { - "name": "login", - "value": "Login" + "name": "listen_mode", + "value": "监听方式实现深浅模式布局或逻辑的差异" }, { - "name": "follow_system_settings_switch_mode", - "value": "Follow system settings to switch between dark and light modes synchronously" + "name": "light_string", + "value": "Light" }, { - "name": "follow_system_settings", - "value": "Follow system settings" + "name": "product_title00", + "value": "充电宝" }, { - "name": "dark_mode", - "value": "Dark mode" + "name": "product_title01", + "value": "笔记本电脑" }, { - "name": "solution", - "value": "Solution" + "name": "product_title02", + "value": "移动手机" }, { - "name": "2d_subscene_solution", - "value": "2D sub-scene solution" + "name": "product_title03", + "value": "电动按摩椅" }, { - "name": "latest_news", - "value": "Latest news" + "name": "product_title04", + "value": "折叠屏" }, { - "name": "multiple_solutions", - "value": "Solutions (repeated multiple times)" + "name": "product_title05", + "value": "极简潮流背包" }, { - "name": "today", - "value": "Today" + "name": "product_price00", + "value": "¥79.9" }, { - "name": "lunar_september_fourth", - "value": "Fourth day of the ninth lunar month" + "name": "product_price01", + "value": "¥6975.8" }, { - "name": "all", - "value": "All" + "name": "product_price02", + "value": "¥4279.6" }, { - "name": "home", - "value": "Home" + "name": "product_price03", + "value": "¥5385.4" }, { - "name": "discover", - "value": "Discover" + "name": "product_price04", + "value": "¥1252.9" }, { - "name": "mine", - "value": "Mine" + "name": "product_price05", + "value": "¥105.3" }, { - "name": "my_account", - "value": "My account" + "name": "product_view00", + "value": "3.2W" }, { - "name": "xiaoyi", - "value": "Xiaoyi" + "name": "product_view01", + "value": "9.8k" }, { - "name": "follow_system", - "value": "Follow system settings" + "name": "product_view02", + "value": "1.8k" }, { - "name": "todo_item_title", - "value": "Get up and go running for exercise to strengthen your body and improve your health." + "name": "product_view03", + "value": "859" + }, + { + "name": "product_view04", + "value": "4.7W" + }, + { + "name": "product_view05", + "value": "1.2W" + }, + { + "name": "warning_text_title", + "value": "功能描述" + }, + { + "name": "warning_text", + "value": "通过系统设置界面手动调整颜色模式选项,应用内深浅色适配设计才能得到实际展现。" + }, + { + "name": "search_text", + "value": "精品好礼" + }, + { + "name": "new_product_text", + "value": "新品首发" + }, + { + "name": "mode_other_function", + "value": "仅演示,可自行实现业务功能" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/media/dark_mode_banner_en.png b/entry/src/main/resources/base/media/dark_mode_banner_en.png new file mode 100644 index 0000000000000000000000000000000000000000..06c0199bd0f149d188065704a5925311cd9f283d Binary files /dev/null and b/entry/src/main/resources/base/media/dark_mode_banner_en.png differ diff --git a/entry/src/main/resources/base/media/light_mode_banner.jpg b/entry/src/main/resources/base/media/light_mode_banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..915315db0921ca5d6b8a10e39a05f551aa5b30d3 Binary files /dev/null and b/entry/src/main/resources/base/media/light_mode_banner.jpg differ diff --git a/entry/src/main/resources/base/media/light_mode_banner_en.png b/entry/src/main/resources/base/media/light_mode_banner_en.png new file mode 100644 index 0000000000000000000000000000000000000000..9feb069aaeb8c51e7fad96f6981473f5ba6f117d Binary files /dev/null and b/entry/src/main/resources/base/media/light_mode_banner_en.png differ diff --git a/entry/src/main/resources/base/media/logo.png b/entry/src/main/resources/base/media/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..523fe863b9bdd8f1d80932ac99757f37e532d485 Binary files /dev/null and b/entry/src/main/resources/base/media/logo.png differ diff --git a/entry/src/main/resources/base/media/product00.png b/entry/src/main/resources/base/media/product00.png new file mode 100644 index 0000000000000000000000000000000000000000..0836f3e45030a303486db7f368d61e8c5fe31daf Binary files /dev/null and b/entry/src/main/resources/base/media/product00.png differ diff --git a/entry/src/main/resources/base/media/product01.png b/entry/src/main/resources/base/media/product01.png new file mode 100644 index 0000000000000000000000000000000000000000..fc998c51ae7fbf2e9d92850d7828082aa68b872f Binary files /dev/null and b/entry/src/main/resources/base/media/product01.png differ diff --git a/entry/src/main/resources/base/media/product02.jpg b/entry/src/main/resources/base/media/product02.jpg new file mode 100644 index 0000000000000000000000000000000000000000..975db9ae5d0af190fceb0aa5797f57eb61073025 Binary files /dev/null and b/entry/src/main/resources/base/media/product02.jpg differ diff --git a/entry/src/main/resources/base/media/product03.png b/entry/src/main/resources/base/media/product03.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e65ebffb6d65b6c4e5a53d5b5051d4aaef3a39 Binary files /dev/null and b/entry/src/main/resources/base/media/product03.png differ diff --git a/entry/src/main/resources/base/media/product04.png b/entry/src/main/resources/base/media/product04.png new file mode 100644 index 0000000000000000000000000000000000000000..b2c84a35e62cc920dd359ad2ee6b404f4957f376 Binary files /dev/null and b/entry/src/main/resources/base/media/product04.png differ diff --git a/entry/src/main/resources/base/media/product05.png b/entry/src/main/resources/base/media/product05.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a50da0ef61692f020e4c29bfe972edfc5c4216 Binary files /dev/null and b/entry/src/main/resources/base/media/product05.png differ diff --git a/entry/src/main/resources/base/media/scan.png b/entry/src/main/resources/base/media/scan.png new file mode 100644 index 0000000000000000000000000000000000000000..fda92d4f4695d08f6ca3cc96ae675b33d3c053c1 Binary files /dev/null and b/entry/src/main/resources/base/media/scan.png differ diff --git a/entry/src/main/resources/base/media/search.png b/entry/src/main/resources/base/media/search.png new file mode 100644 index 0000000000000000000000000000000000000000..8bc3b1eec293469c3dcadc6dd5a39649b6de1bea Binary files /dev/null and b/entry/src/main/resources/base/media/search.png differ diff --git a/entry/src/main/resources/base/media/view.svg b/entry/src/main/resources/base/media/view.svg new file mode 100644 index 0000000000000000000000000000000000000000..a8fc8a619e4c7b6610ac18d742be38a281fffd25 --- /dev/null +++ b/entry/src/main/resources/base/media/view.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/dark/element/color.json b/entry/src/main/resources/dark/element/color.json index a1defb7e660e0a73869c6af6447802c0919db221..66c51c713d59ea61a86a2162a5f831a28538790c 100644 --- a/entry/src/main/resources/dark/element/color.json +++ b/entry/src/main/resources/dark/element/color.json @@ -1,64 +1,24 @@ { "color": [ { - "name": "sub_title_color", - "value": "#E6FFFFFF" - }, - { - "name": "app_background_color", + "name": "page_bg_color", "value": "#000000" }, { - "name": "sub_title_date", - "value": "#66FFFFFF" - }, - { - "name": "font_color", - "value": "#E6FFFFFF" - }, - { - "name": "item_box", - "value": "#1A1A1A" - }, - { - "name": "todo_date", - "value": "#66FFFFFF" - }, - { - "name": "todo_time", - "value": "#E6FFFFFF" - }, - { - "name": "sub_text_color", - "value": "#99FFFFFF" - }, - { - "name": "bell_color", - "value": "#E6000000" - }, - { - "name": "horizon_box", - "value": "#33FFFFFF" - }, - { - "name": "arrow_color", - "value": "#999999" - }, - { - "name": "icon_bg_color", - "value": "#1a1a1a" + "name": "column_bg_color", + "value": "#000000" }, { - "name": "left_icon_color", - "value": "#5f5f5f" + "name": "product_bg_color", + "value": "#000000" }, { - "name": "right_icon_color", - "value": "#e9e9e9" + "name": "custom_bg_color", + "value": "#000000" }, { - "name": "tab_bar_background_color", - "value": "#40000000" + "name": "view_fill_color", + "value": "#FFFFFF" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/dark/media/dark_mode_banner.jpg b/entry/src/main/resources/dark/media/dark_mode_banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1a02c8c6d861998f90760e9747a7805c143b2d6c Binary files /dev/null and b/entry/src/main/resources/dark/media/dark_mode_banner.jpg differ diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json index 47146b406ccaa97f91bab0a3fe3c4a7e6b885d4b..7584cc7e6357d203cd5171f50d495b2ee8df1e8b 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/entry/src/main/resources/en_US/element/string.json @@ -1,108 +1,48 @@ { "string": [ { - "name": "module_desc", - "value": "module description" + "name": "warning_text_title", + "value": "Description of the function" }, { - "name": "EntryAbility_desc", - "value": "description" + "name": "warning_text", + "value": "Manually adjust the color mode options through the system settings interface to actually show off the color adaptation design in the app." }, { - "name": "EntryAbility_label", - "value": "FitForDarkMode" + "name": "search_text", + "value": "Boutique gifts" }, { - "name": "today_plan", - "value": "Sprint review for IELTS exam, Chapter 3, comprehensive review" + "name": "new_product_text", + "value": "New product debut" }, { - "name": "end", - "value": "End" + "name": "mode_other_function", + "value": "Demo only, you can implement business functions on your own" }, { - "name": "already_reported", - "value": "Time already reported" + "name": "product_title00", + "value": "Power bank" }, { - "name": "please_input_account", - "value": "Please enter your account" + "name": "product_title01", + "value": "laptop" }, { - "name": "please_input_password", - "value": "Please enter your password" + "name": "product_title02", + "value": "Mobile phones" }, { - "name": "login", - "value": "Login" + "name": "product_title03", + "value": "Electric massage chair" }, { - "name": "follow_system_settings_switch_mode", - "value": "Follow system settings to switch between dark and light modes synchronously" + "name": "product_title04", + "value": "Foldable screen" }, { - "name": "follow_system_settings", - "value": "Follow system settings" - }, - { - "name": "dark_mode", - "value": "Dark mode" - }, - { - "name": "solution", - "value": "Solution" - }, - { - "name": "2d_subscene_solution", - "value": "2D sub-scene solution" - }, - { - "name": "latest_news", - "value": "Latest news" - }, - { - "name": "multiple_solutions", - "value": "Solutions (repeated multiple times)" - }, - { - "name": "today", - "value": "Today" - }, - { - "name": "lunar_september_fourth", - "value": "Fourth day of the ninth lunar month" - }, - { - "name": "all", - "value": "All" - }, - { - "name": "home", - "value": "Home" - }, - { - "name": "discover", - "value": "Discover" - }, - { - "name": "mine", - "value": "Mine" - }, - { - "name": "my_account", - "value": "My account" - }, - { - "name": "xiaoyi", - "value": "Xiaoyi" - }, - { - "name": "follow_system", - "value": "Follow system settings" - }, - { - "name": "todo_item_title", - "value": "Get up and go running for exercise to strengthen your body and improve your health." + "name": "product_title05", + "value": "Minimalist trendy backpack" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index a3d7313e4a628ba69cfe10f448a00e06134f0c7e..e868f096692e9b04db0fc478e4798f4438e54962 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -1,108 +1,48 @@ { "string": [ { - "name": "module_desc", - "value": "module description" + "name": "warning_text_title", + "value": "功能描述" }, { - "name": "EntryAbility_desc", - "value": "description" + "name": "warning_text", + "value": "通过系统设置界面手动调整颜色模式选项,应用内深浅色适配设计才能得到实际展现。" }, { - "name": "EntryAbility_label", - "value": "深色模式适配" + "name": "search_text", + "value": "精品好礼" }, { - "name": "today_plan", - "value": "【今日计划】雅思考试大冲刺复习课程第三章全部" + "name": "new_product_text", + "value": "新品首发" }, { - "name": "end", - "value": "结束" + "name": "mode_other_function", + "value": "仅演示,可自行实现业务功能" }, { - "name": "already_reported", - "value": "已报时" + "name": "product_title00", + "value": "充电宝" }, { - "name": "please_input_account", - "value": "请输入账号" + "name": "product_title01", + "value": "笔记本电脑" }, { - "name": "please_input_password", - "value": "请输入密码" + "name": "product_title02", + "value": "移动手机" }, { - "name": "login", - "value": "登录" + "name": "product_title03", + "value": "电动按摩椅" }, { - "name": "follow_system_settings_switch_mode", - "value": "跟随系统设置开启后根据系统设置同步切换深/浅模式" + "name": "product_title04", + "value": "折叠屏" }, { - "name": "follow_system_settings", - "value": "跟随系统设置" - }, - { - "name": "dark_mode", - "value": "深色模式" - }, - { - "name": "solution", - "value": "解决方案" - }, - { - "name": "2d_subscene_solution", - "value": "2D子场景解决方案" - }, - { - "name": "latest_news", - "value": "最新资讯" - }, - { - "name": "multiple_solutions", - "value": "解决方案解决方案解决方案解决方案解决方案" - }, - { - "name": "today", - "value": "今天" - }, - { - "name": "lunar_september_fourth", - "value": "农历九月初四" - }, - { - "name": "all", - "value": "全部" - }, - { - "name": "home", - "value": "首页" - }, - { - "name": "discover", - "value": "发现" - }, - { - "name": "mine", - "value": "我的" - }, - { - "name": "my_account", - "value": "我的账户" - }, - { - "name": "xiaoyi", - "value": "小艺" - }, - { - "name": "follow_system", - "value": "跟随系统" - }, - { - "name": "todo_item_title", - "value": "起来跑步运动,强身健体" + "name": "product_title05", + "value": "极简潮流背包" } ] } \ No newline at end of file diff --git a/screenshots/dark.png b/screenshots/dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3b9588d0533c7151f10042e0b15ac27dca72cefc Binary files /dev/null and b/screenshots/dark.png differ diff --git a/screenshots/dark_en.png b/screenshots/dark_en.png new file mode 100644 index 0000000000000000000000000000000000000000..d8094092272046fd5a1fcd7448d0ae45fe8759f6 Binary files /dev/null and b/screenshots/dark_en.png differ diff --git a/screenshots/light.png b/screenshots/light.png new file mode 100644 index 0000000000000000000000000000000000000000..34127360111e7ac2279045a2a7273cfd14642aa7 Binary files /dev/null and b/screenshots/light.png differ diff --git a/screenshots/light_en.png b/screenshots/light_en.png new file mode 100644 index 0000000000000000000000000000000000000000..33bead76282b55380ae45a51c2cbc2ed563222a6 Binary files /dev/null and b/screenshots/light_en.png differ