diff --git a/README.en.md b/README.en.md index a40cf35e50693e7f95af5ca01e36508346662fd4..8bbe43e787a2121e2ce638330d800828a4ee4b59 100644 --- a/README.en.md +++ b/README.en.md @@ -15,23 +15,30 @@ This sample describes how to use component stacking to build multi-layer stack v ### Project Directory ``` -componentstack -├──entry/src/main/ets -│ ├──constant -│ │ └──StackConstant.ets // Constant class -│ ├──entryability -│ │ └──EntryAbility.ets // Application lifecycle class -│ ├──model -│ │ └──IconModel.ets // Local data source -│ ├──pages -│ │ └──Index.ets // Home page of component stacking -│ ├──view -│ │ ├──IconView.ets // Custom component of the icon shortcut -│ │ └──ProductList.ets // Custom component of the product list -│ └──viewmodel -│ ├──DataSource.ets // List data model -│ └──IconModel.ets // Data type definition -└────entry/src/main/resources +component-stack +├──componentstacklibrary/src/main/ets +│ ├──component +│ │ └──ComponentStackComponent.ets // Component stacking component class +│ ├──constant +│ │ └──CommonConstants.ets // Constants class +│ ├──model +│ │ └──IconModel.ets // Local data source +│ ├──utils +│ │ ├───BreakpointSystem.ets // Responsive layout class (for multi-device adaptation) +│ │ └───WindowUtil.ets // General window utility class +│ ├──view +│ │ ├──IconView.ets // Quick access button custom component +│ │ └──ProductList.ets // Product list custom component +│ └──viewmodel +│ ├──DataSource.ets // List data model +│ └──IconModel.ets // Data type definition +└────componentstacklibrary/src/main/resources +├──componentstacksample/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // Application lifecycle class +│ ├──pages +│ │ └──Index.ets // Main page for component stacking +└────componentstacksample/src/main/resources ``` ### How to Implement diff --git a/README.md b/README.md index bb81ab753b378ba058d43f431f7f8d91cd4bab41..c91059d2328d76b7e89813c8e103506e7cc5c35a 100644 --- a/README.md +++ b/README.md @@ -15,23 +15,30 @@ ### 目录结构 ``` -componentstack -├──entry/src/main/ets +component-stack +├──componentstacklibrary/src/main/ets +│ ├──component +│ │ └──ComponentStackComponent.ets // 组件堆叠组件类 │ ├──constant -│ │ └──StackConstant.ets // 常量类 -│ ├──entryability -│ │ └──EntryAbility.ets // 应用生命周期类 +│ │ └──CommonConstants.ets // 常量类 │ ├──model -│ │ └──IconModel.ets // 本地数据源 -│ ├──pages -│ │ └──Index.ets // 组件堆叠主页面 +│ │ └──IconModel.ets // 本地数据源 +│ ├──utils +│ │ ├───BreakpointSystem.ets // 一多类 +│ │ └───WindowUtil.ets // 通用窗口类 │ ├──view -│ │ ├──IconView.ets // 按钮快捷入口自定义组件 -│ │ └──ProductList.ets // 商品列表自定义组件 +│ │ ├──IconView.ets // 按钮快捷入口自定义组件 +│ │ └──ProductList.ets // 商品列表自定义组件 │ └──viewmodel -│ ├──DataSource.ets // 列表数据模型 -│ └──IconModel.ets // 数据类型定义 -└────entry/src/main/resources +│ ├──DataSource.ets // 列表数据模型 +│ └──IconModel.ets // 数据类型定义 +└────componentstacklibrary/src/main/resources +├──componentstacksample/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets // 应用生命周期类 +│ ├──pages +│ │ └──Index.ets // 组件堆叠主页面 +└────componentstacksample/src/main/resources ``` ### 实现思路 diff --git a/componentstacklibrary/BuildProfile.ets b/componentstacklibrary/BuildProfile.ets new file mode 100644 index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4 --- /dev/null +++ b/componentstacklibrary/BuildProfile.ets @@ -0,0 +1,17 @@ +/** + * Use these variables when you tailor your ArkTS code. They must be of the const type. + */ +export const HAR_VERSION = '1.0.0'; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; +export const TARGET_NAME = 'default'; + +/** + * BuildProfile Class is used only for compatibility purposes. + */ +export default class BuildProfile { + static readonly HAR_VERSION = HAR_VERSION; + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; + static readonly DEBUG = DEBUG; + static readonly TARGET_NAME = TARGET_NAME; +} \ No newline at end of file diff --git a/componentstacklibrary/Index.ets b/componentstacklibrary/Index.ets index 8f9d01b186dca7a1e36e439e26c5c8ca7cfb745f..baab691a7deaca7fdf1d65bf08570a84aaa098ae 100644 --- a/componentstacklibrary/Index.ets +++ b/componentstacklibrary/Index.ets @@ -1,2 +1,3 @@ -export { ComponentStackPage} from './src/main/ets/pages/ComponentStackPage' -export { WindowUtil } from './src/main/ets/utils/WindowUtil'; \ No newline at end of file +export { ComponentStackComponent } from './src/main/ets/component/ComponentStackComponent'; + +export { ComponentStackController } from './src/main/ets/ComponentStackController.ets'; \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/ComponentStackController.ets b/componentstacklibrary/src/main/ets/ComponentStackController.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf9a4f63cf638ee231a1e83497ab85b7641c6566 --- /dev/null +++ b/componentstacklibrary/src/main/ets/ComponentStackController.ets @@ -0,0 +1,28 @@ +/* + * 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 { window } from '@kit.ArkUI'; +import { WindowUtil } from './utils/WindowUtil'; +import { common } from '@kit.AbilityKit'; + +export class ComponentStackController { + public static initWindowConfig(windowStage: window.WindowStage): void { + WindowUtil.initialize(windowStage); + } + + public static updatedColorMode(context: common.UIAbilityContext): void { + WindowUtil.updatedColorMode(context); + } +} \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/pages/ComponentStackPage.ets b/componentstacklibrary/src/main/ets/component/ComponentStackComponent.ets similarity index 63% rename from componentstacklibrary/src/main/ets/pages/ComponentStackPage.ets rename to componentstacklibrary/src/main/ets/component/ComponentStackComponent.ets index 3eae1976f65391ef19cc4e9c9d6d40bfdf6a3f3c..d2de0dd9681fc659e561c1d7c8f772036cf82334 100644 --- a/componentstacklibrary/src/main/ets/pages/ComponentStackPage.ets +++ b/componentstacklibrary/src/main/ets/component/ComponentStackComponent.ets @@ -13,24 +13,24 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; import { IconList1, IconList2, IconList3 } from '../view/IconView'; -import { StackConstant } from '../constant/StackConstant'; import { ProductList } from '../view/ProductList'; +import { CommonConstants } from '../constants/CommonConstants'; +import { BreakpointTypeEnum } from '../utils/BreakpointSystem'; @Component -export struct ComponentStackPage { - @State searchHeight: number = StackConstant.SEARCH_HEIGHT_RAW; +export struct ComponentStackComponent { + @State searchHeight: number = CommonConstants.SEARCH_HEIGHT_RAW; @State opacityList: number = 1; @State opacityList2: number = 1; @State ratio: number = 1; @State isChange: boolean = false; - @State heightList2: number = StackConstant.HEIGHT_LIST_2_RAW; - @State marginSpace: number = StackConstant.MAX_MARGIN_SPACE; - @StorageLink('statusHeight') statusHeight: number = 0; - @StorageLink('bottomHeight') bottomHeight: number = 0; - @StorageLink('screenHeight') screenHeight: number = 0; - @StorageLink('currentBreakpoint') curBp: string = StackConstant.BREAK_POINT_SM; + @State heightList2: number = CommonConstants.HEIGHT_LIST_2_RAW; + @State marginSpace: number = CommonConstants.MAX_MARGIN_SPACE; + @StorageLink(CommonConstants.KEY_PREFIX + 'statusBarHeight') statusBarHeight: number = 0; + @StorageLink(CommonConstants.KEY_PREFIX + 'navigatorBarHeight') navigatorBarHeight: number = 0; + @StorageLink(CommonConstants.KEY_PREFIX + 'screenHeight') screenHeight: number = 0; + @StorageLink(CommonConstants.KEY_PREFIX + 'currentBreakpoint') curBp: string = BreakpointTypeEnum.SM; private scroller: Scroller = new Scroller(); private scroller2: Scroller = new Scroller(); @@ -50,7 +50,7 @@ export struct ComponentStackPage { .padding({ top: $r('app.integer.flex_padding_top') }) - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.flex_height')) Scroll(this.scroller) { @@ -67,12 +67,14 @@ export struct ComponentStackPage { .fontSize($r('app.integer.search_font_size')) .margin({ left: $r('app.integer.search_text_margin_left') }) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height(this.searchHeight) .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius($r('app.integer.search_border_radius')) .onClick(() => { - promptAction.showToast({ message: $r('app.string.component_stack_other_function') }); + this.getUIContext() + .getPromptAction() + .showToast({ message: $r('app.string.component_stack_other_function') }); }); Stack({ alignContent: Alignment.Top }) { @@ -80,8 +82,8 @@ export struct ComponentStackPage { Row() { IconList3({ marginSpace: this.marginSpace }) } - .backgroundColor($r('sys.color.comp_background_primary')) - .width(StackConstant.FULL_PERCENT) + .backgroundColor($r('sys.color.background_secondary')) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_list_height3')) .opacity(this.opacityList) .zIndex(1) @@ -89,7 +91,7 @@ export struct ComponentStackPage { Row() { IconList1() } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_list_height1')) .opacity(this.opacityList) } @@ -99,17 +101,18 @@ export struct ComponentStackPage { Row() { IconList2({ ratio: this.ratio }) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_view_height3')) .opacity(this.opacityList2) ProductList() - .width(StackConstant.FULL_PERCENT) - .height(px2vp(this.screenHeight - this.statusHeight - this.bottomHeight) - StackConstant.USED_SPACE) + .width(CommonConstants.FULL_PERCENT) + .height(this.getUIContext().px2vp(this.screenHeight - this.statusBarHeight - this.navigatorBarHeight) - + CommonConstants.USED_SPACE) } - .margin({ top: StackConstant.MARGIN_TOP }) + .margin({ top: CommonConstants.MARGIN_TOP }) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .scrollBar(BarState.Off) // Sets the nested scrolling mode in the forward and backward directions to implement // scrolling linkage with the parent widget. @@ -122,54 +125,55 @@ export struct ComponentStackPage { .onScrollFrameBegin((offset: number) => { // Change the values of margin and opacity to move and hide the component. let yOffset: number = this.scroller2.currentOffset().yOffset; - this.heightList2 = StackConstant.HEIGHT_LIST_2_RAW - yOffset * 0.5; + this.heightList2 = CommonConstants.HEIGHT_LIST_2_RAW - yOffset * 0.5; // Set the transparency of IconList2 based on the yOffset value. - if (1 - yOffset / StackConstant.ICON_LIST_2_RAW >= 0) { - this.opacityList2 = 1 - yOffset / StackConstant.ICON_LIST_2_RAW; + if (1 - yOffset / CommonConstants.ICON_LIST_2_RAW >= 0) { + this.opacityList2 = 1 - yOffset / CommonConstants.ICON_LIST_2_RAW; } else { - this.opacityList2 = 0; + this.opacityList2 = 0;11 } // Zoom with transparency settings. this.ratio = this.opacityList2; // Set the transparency of IconList1 and the margin of IconList3 based on yOffset. - if (1 - yOffset / StackConstant.ICON_LIST_1_RAW > 0) { + if (1 - yOffset / CommonConstants.ICON_LIST_1_RAW > 0) { this.isChange = false; - this.opacityList = 1 - yOffset / StackConstant.ICON_LIST_1_RAW; - this.marginSpace = StackConstant.MAX_MARGIN_SPACE; + this.opacityList = 1 - yOffset / CommonConstants.ICON_LIST_1_RAW; + this.marginSpace = CommonConstants.MAX_MARGIN_SPACE; } else { this.isChange = true; - this.opacityList = (yOffset - StackConstant.ICON_LIST_1_RAW) / StackConstant.MAX_MARGIN_SPACE; - this.marginSpace = StackConstant.ICON_LIST_3_RAW - yOffset > StackConstant.MIN_MARGIN_SPACE ? - (StackConstant.ICON_LIST_3_RAW - yOffset) : StackConstant.MIN_MARGIN_SPACE; + this.opacityList = (yOffset - CommonConstants.ICON_LIST_1_RAW) / CommonConstants.MAX_MARGIN_SPACE; + this.marginSpace = CommonConstants.ICON_LIST_3_RAW - yOffset > CommonConstants.MIN_MARGIN_SPACE ? + (CommonConstants.ICON_LIST_3_RAW - yOffset) : CommonConstants.MIN_MARGIN_SPACE; } return { offsetRemain: offset }; }) } } - .height(StackConstant.FULL_PERCENT) - .width(StackConstant.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .margin({ top: $r('app.integer.margin_search_view') }) } - .width(StackConstant.FULL_PERCENT) - .height(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) .scrollBar(BarState.Off) + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) .onScrollFrameBegin((offset: number) => { // Obtains the sliding distance. const yOffset: number = this.scroller.currentOffset().yOffset; - this.searchHeight = StackConstant.SEARCH_HEIGHT_RAW - yOffset * 0.6; + this.searchHeight = CommonConstants.SEARCH_HEIGHT_RAW - yOffset * 0.6; return { offsetRemain: offset }; }) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .layoutWeight(1) .backgroundColor($r('sys.color.background_secondary')) .padding({ - top: this.statusHeight, + top: this.statusBarHeight, left: this.curBp === 'sm' ? $r('sys.float.padding_level8') : - this.curBp === 'md' ? $r('sys.float.padding_level12') : $r('sys.float.padding_level16'), + this.curBp === 'md' ? $r('sys.float.padding_level12') : $r('sys.float.padding_level16'), right: this.curBp === 'sm' ? $r('sys.float.padding_level8') : - this.curBp === 'md' ? $r('sys.float.padding_level12') : $r('sys.float.padding_level16'), + this.curBp === 'md' ? $r('sys.float.padding_level12') : $r('sys.float.padding_level16'), }) } } \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/constant/StackConstant.ets b/componentstacklibrary/src/main/ets/constants/CommonConstants.ets similarity index 71% rename from componentstacklibrary/src/main/ets/constant/StackConstant.ets rename to componentstacklibrary/src/main/ets/constants/CommonConstants.ets index b4f6e5ebcdbaafc96393995b9f581de868867d20..13a1f2902fe9b5e7cb217cdd28f7dfe915a2214b 100644 --- a/componentstacklibrary/src/main/ets/constant/StackConstant.ets +++ b/componentstacklibrary/src/main/ets/constants/CommonConstants.ets @@ -1,19 +1,6 @@ -/* - * 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 StackConstant { + + +export class CommonConstants { /** * Initial height of the backup search box. */ @@ -98,9 +85,8 @@ export class StackConstant { * 100 percent. */ public static readonly FULL_PERCENT: string = '100%'; - /** - * Breakpoint sm. + * AppStorage key prefix. */ - public static readonly BREAK_POINT_SM: string = 'sm'; + public static readonly KEY_PREFIX: string = 'componentStack'; } \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/model/IconModel.ets b/componentstacklibrary/src/main/ets/model/IconModel.ets index ae08d2375dc9cbacc213ef668b731b59a05a48f2..266c326d1ee0da51bbf2cada1245105e12b77ee5 100644 --- a/componentstacklibrary/src/main/ets/model/IconModel.ets +++ b/componentstacklibrary/src/main/ets/model/IconModel.ets @@ -36,10 +36,40 @@ export const ICON_DATA2: IconDataModel[] = [ // Offering List Data Source. export const PRODUCT_DATA: ProductDataModel[] = [ - new ProductDataModel(0, $r('app.media.product00'), $r('app.string.product_title00'), $r('app.string.product_price00'), $r('app.string.product_insurance00')), - new ProductDataModel(1, $r('app.media.product01'), $r('app.string.product_title01'), $r('app.string.product_price01'), $r('app.string.product_insurance01')), - new ProductDataModel(2, $r('app.media.product02'), $r('app.string.product_title02'), $r('app.string.product_price02'), $r('app.string.product_insurance02')), - new ProductDataModel(3, $r('app.media.product03'), $r('app.string.product_title03'), $r('app.string.product_price03'), $r('app.string.product_insurance03')), - new ProductDataModel(4, $r('app.media.product04'), $r('app.string.product_title04'), $r('app.string.product_price04'), $r('app.string.product_insurance04')), - new ProductDataModel(5, $r('app.media.product03'), $r('app.string.product_title03'), $r('app.string.product_price03'), $r('app.string.product_insurance05')) + new ProductDataModel(0, $r('app.media.product00'), $r('app.string.product_title00'), $r('app.string.product_price00'), + $r('app.string.product_insurance00')), + new ProductDataModel(1, $r('app.media.product01'), $r('app.string.product_title01'), $r('app.string.product_price01'), + $r('app.string.product_insurance01')), + new ProductDataModel(2, $r('app.media.product02'), $r('app.string.product_title02'), $r('app.string.product_price02'), + $r('app.string.product_insurance02')), + new ProductDataModel(3, $r('app.media.product03'), $r('app.string.product_title03'), $r('app.string.product_price03'), + $r('app.string.product_insurance03')), + new ProductDataModel(4, $r('app.media.product04'), $r('app.string.product_title04'), $r('app.string.product_price04'), + $r('app.string.product_insurance04')), + new ProductDataModel(5, $r('app.media.product03'), $r('app.string.product_title03'), $r('app.string.product_price03'), + $r('app.string.product_insurance05')), + new ProductDataModel(6, $r('app.media.product00'), $r('app.string.product_title00'), $r('app.string.product_price00'), + $r('app.string.product_insurance00')), + new ProductDataModel(7, $r('app.media.product01'), $r('app.string.product_title01'), $r('app.string.product_price01'), + $r('app.string.product_insurance01')), + new ProductDataModel(8, $r('app.media.product02'), $r('app.string.product_title02'), $r('app.string.product_price02'), + $r('app.string.product_insurance02')), + new ProductDataModel(9, $r('app.media.product03'), $r('app.string.product_title03'), $r('app.string.product_price03'), + $r('app.string.product_insurance03')), + new ProductDataModel(10, $r('app.media.product04'), $r('app.string.product_title04'), + $r('app.string.product_price04'), $r('app.string.product_insurance04')), + new ProductDataModel(11, $r('app.media.product03'), $r('app.string.product_title03'), + $r('app.string.product_price03'), $r('app.string.product_insurance05')), + new ProductDataModel(12, $r('app.media.product00'), $r('app.string.product_title00'), + $r('app.string.product_price00'), $r('app.string.product_insurance00')), + new ProductDataModel(13, $r('app.media.product01'), $r('app.string.product_title01'), + $r('app.string.product_price01'), $r('app.string.product_insurance01')), + new ProductDataModel(14, $r('app.media.product02'), $r('app.string.product_title02'), + $r('app.string.product_price02'), $r('app.string.product_insurance02')), + new ProductDataModel(15, $r('app.media.product03'), $r('app.string.product_title03'), + $r('app.string.product_price03'), $r('app.string.product_insurance03')), + new ProductDataModel(16, $r('app.media.product04'), $r('app.string.product_title04'), + $r('app.string.product_price04'), $r('app.string.product_insurance04')), + new ProductDataModel(17, $r('app.media.product03'), $r('app.string.product_title03'), + $r('app.string.product_price03'), $r('app.string.product_insurance05')) ]; \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/utils/BreakpointSystem.ets b/componentstacklibrary/src/main/ets/utils/BreakpointSystem.ets index aa7581b2047323eac83c8d9a031e21faabc55bd2..02feb5558f7f7ba545e737597ca4283a476a1dbb 100644 --- a/componentstacklibrary/src/main/ets/utils/BreakpointSystem.ets +++ b/componentstacklibrary/src/main/ets/utils/BreakpointSystem.ets @@ -16,6 +16,7 @@ import { window } from '@kit.ArkUI'; import type { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; +import { CommonConstants } from '../constants/CommonConstants'; const TAG: string = '[BreakpointSystem]'; @@ -82,10 +83,8 @@ export class BreakpointSystem { } public updateCurrentBreakpoint(breakpoint: BreakpointTypeEnum): void { - if (this.currentBreakpoint !== breakpoint) { this.currentBreakpoint = breakpoint; - AppStorage.setOrCreate('currentBreakpoint', this.currentBreakpoint); - } + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'currentBreakpoint', this.currentBreakpoint); } public onWindowSizeChange(window: window.Window): void { @@ -94,9 +93,10 @@ export class BreakpointSystem { public updateWidthBp(window: window.Window): void { try { + const uiContext: UIContext = AppStorage.get(CommonConstants.KEY_PREFIX + 'UIContext') as UIContext; const mainWindow: window.WindowProperties = window.getWindowProperties(); const windowWidth: number = mainWindow.windowRect.width; - const windowWidthVp = px2vp(windowWidth); + const windowWidthVp = uiContext.px2vp(windowWidth); let widthBp: BreakpointTypeEnum = BreakpointTypeEnum.MD; if (windowWidthVp < 320) { widthBp = BreakpointTypeEnum.XS; diff --git a/componentstacklibrary/src/main/ets/utils/WindowUtil.ets b/componentstacklibrary/src/main/ets/utils/WindowUtil.ets index 75b2e8075fc81bb9a4980d776f4c52481b8bd4b4..6a37e2bf56a7344f4a2d13c4d73d7822c1718dd9 100644 --- a/componentstacklibrary/src/main/ets/utils/WindowUtil.ets +++ b/componentstacklibrary/src/main/ets/utils/WindowUtil.ets @@ -15,13 +15,30 @@ import { window } from '@kit.ArkUI'; import type { BusinessError } from '@kit.BasicServicesKit'; -import { BreakpointSystem } from './BreakpointSystem'; import { hilog } from '@kit.PerformanceAnalysisKit'; -import { Configuration, ConfigurationConstant } from '@kit.AbilityKit'; +import { common, Configuration, ConfigurationConstant } from '@kit.AbilityKit'; +import { CommonConstants } from '../constants/CommonConstants'; +import { BreakpointSystem } from './BreakpointSystem'; const TAG: string = '[WindowUtil]'; export class WindowUtil { + private static windowClass?: window.Window; + private static uiContext: UIContext; + + public static initialize(windowStage: window.WindowStage) { + try { + WindowUtil.windowClass = windowStage.getMainWindowSync(); + const uiContext: UIContext = WindowUtil.windowClass.getUIContext(); + WindowUtil.uiContext = uiContext; + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'UIContext', uiContext); + WindowUtil.registerBreakPoint(windowStage); + WindowUtil.requestFullScreen(windowStage); + } catch (err) { + hilog.error(0x0000, TAG, `WindowUtil initialize failed. Cause: ${err.code} ${err.message}`); + } + } + public static requestFullScreen(windowStage: window.WindowStage): void { windowStage.getMainWindow((err: BusinessError, data: window.Window) => { if (err.code) { @@ -34,11 +51,11 @@ export class WindowUtil { promise.then(() => { hilog.info(0x0000, TAG, 'Succeeded in setting the window layout to full-screen mode.'); }).catch((err: BusinessError) => { - hilog.info(0x0000, TAG, + hilog.error(0x0000, TAG, `Failed to set the window layout to full-screen mode. Cause: ${err.code}, ${err.message}`); }); } catch { - hilog.error(0x0000, TAG, 'Failed to set the window layout to full-screen mode. '); + hilog.error(0x0000, TAG, 'Failed to set the window layout to full-screen mode.'); } }); } @@ -50,8 +67,15 @@ export class WindowUtil { return; } BreakpointSystem.getInstance().updateWidthBp(data); + let avoidArea = data.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'navigatorBarHeight', + WindowUtil.uiContext.px2vp(avoidArea.bottomRect.height)); + avoidArea = data.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'statusBarHeight', + WindowUtil.uiContext.px2vp(avoidArea.topRect.height)); data.on('windowSizeChange', () => BreakpointSystem.getInstance().onWindowSizeChange(data)); data.on('avoidAreaChange', (avoidAreaOption) => { + WindowUtil.setAvoidArea(avoidAreaOption.type, avoidAreaOption.area); if (avoidAreaOption.type === window.AvoidAreaType.TYPE_SYSTEM || avoidAreaOption.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { WindowUtil.setAvoidArea(avoidAreaOption.type, avoidAreaOption.area); @@ -63,18 +87,15 @@ export class WindowUtil { // Get status bar height and indicator height. public static setAvoidArea(type: window.AvoidAreaType, area: window.AvoidArea) { if (type === window.AvoidAreaType.TYPE_SYSTEM) { - AppStorage.setOrCreate('statusHeight', px2vp(area.topRect.height)); + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'statusBarHeight', + WindowUtil.uiContext.px2vp(area.topRect.height)); } else { - AppStorage.setOrCreate('bottomHeight', px2vp(area.bottomRect.height)); + AppStorage.setOrCreate(CommonConstants.KEY_PREFIX + 'navigatorBarHeight', + WindowUtil.uiContext.px2vp(area.bottomRect.height)); } } - public static updatedColorMode(newConfig: Configuration): void { - let newColorMode: ConfigurationConstant.ColorMode = - newConfig.colorMode || ConfigurationConstant.ColorMode.COLOR_MODE_DARK; - let currentColorMode = AppStorage.get('systemColorMode'); - if (newColorMode !== currentColorMode) { - AppStorage.setOrCreate('systemColorMode', newColorMode); - } + public static updatedColorMode(context: common.UIAbilityContext): void { + context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); } } \ No newline at end of file diff --git a/componentstacklibrary/src/main/ets/view/IconView.ets b/componentstacklibrary/src/main/ets/view/IconView.ets index 78df7253668281a5af85aebe81dddbe7e22eed59..e0540e95e17feb5783ffce92302e56c45b76e5fa 100644 --- a/componentstacklibrary/src/main/ets/view/IconView.ets +++ b/componentstacklibrary/src/main/ets/view/IconView.ets @@ -13,10 +13,9 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; import { ICON_DATA1, ICON_DATA2 } from '../model/IconModel'; import { IconDataModel } from '../viewmodel/IconViewModel'; -import { StackConstant } from '../constant/StackConstant'; +import { CommonConstants } from '../constants/CommonConstants'; // White background style of the lower text in the preceding figure. @Component @@ -25,7 +24,7 @@ struct IconView1 { title: ResourceStr = ''; build() { - Column({ space: StackConstant.ICON_VIEW_SPACE }) { + Column({ space: CommonConstants.ICON_VIEW_SPACE }) { Image(this.icon) .width($r('app.integer.icon_view_width')) .aspectRatio(1) @@ -36,13 +35,13 @@ struct IconView1 { .fontColor($r('sys.color.font_primary')) .textAlign(TextAlign.Center) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_view_height')) .justifyContent(FlexAlign.Center) .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius($r('app.integer.icon_view_border_radius')) .onClick(() => { - promptAction.showToast({ message: $r('app.string.component_stack_other_function') }); + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.component_stack_other_function') }); }) } } @@ -64,13 +63,13 @@ struct IconView2 { .objectFit(ImageFit.Contain) .margin({ left: $r('app.integer.icon_view_image_margin_left') }) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_view_height2')) .justifyContent(FlexAlign.Center) .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius($r('app.integer.icon_view_border_radius')) .onClick(() => { - promptAction.showToast({ message: $r('app.string.component_stack_other_function') }); + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.component_stack_other_function') }); }) } } @@ -82,7 +81,7 @@ struct IconView3 { title: ResourceStr = ''; build() { - Column({ space: StackConstant.ICON_VIEW_SPACE }) { + Column({ space: CommonConstants.ICON_VIEW_SPACE }) { Image(this.icon) .width(30) .aspectRatio(1) @@ -92,11 +91,11 @@ struct IconView3 { .fontColor($r('sys.color.font_primary')) .textAlign(TextAlign.Center) } - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.icon_view_height3')) .justifyContent(FlexAlign.Center) .onClick(() => { - promptAction.showToast({ message: $r('app.string.component_stack_other_function') }); + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.component_stack_other_function') }); }) } } @@ -105,10 +104,10 @@ struct IconView3 { export struct IconList1 { build() { GridRow({ - columns: StackConstant.ICON_LIST_COLUMNS_1, + columns: CommonConstants.ICON_LIST_COLUMNS_1, gutter: { - x: StackConstant.ICON_VIEW_SPACE, - y: StackConstant.ICON_VIEW_SPACE + x: CommonConstants.ICON_VIEW_SPACE, + y: CommonConstants.ICON_VIEW_SPACE } }) { ForEach(ICON_DATA1, (item: IconDataModel) => { @@ -130,10 +129,10 @@ export struct IconList2 { build() { GridRow({ - columns: StackConstant.ICON_LIST_COLUMNS_2, + columns: CommonConstants.ICON_LIST_COLUMNS_2, gutter: { - x: StackConstant.ICON_VIEW_SPACE, - y: StackConstant.ICON_VIEW_SPACE + x: CommonConstants.ICON_VIEW_SPACE, + y: CommonConstants.ICON_VIEW_SPACE } }) { ForEach(ICON_DATA2, (item: IconDataModel) => { @@ -161,7 +160,7 @@ export struct IconList3 { }, (item: IconDataModel) => item.id.toString()) } .height($r('app.integer.icon_view_height')) - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .listDirection(Axis.Horizontal) .scrollBar(BarState.Off) } diff --git a/componentstacklibrary/src/main/ets/view/ProductList.ets b/componentstacklibrary/src/main/ets/view/ProductList.ets index 756107dafef0170528c7ec9fa8db67346f7ac694..b0631581818ee2ff9fa2f99bd3ea779a536b3084 100644 --- a/componentstacklibrary/src/main/ets/view/ProductList.ets +++ b/componentstacklibrary/src/main/ets/view/ProductList.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { promptAction } from '@kit.ArkUI'; import { ProductDataModel } from '../viewmodel/IconViewModel'; import { ProductDataSource } from '../viewmodel/DataSource'; -import { StackConstant } from '../constant/StackConstant'; import { PRODUCT_DATA } from '../model/IconModel'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { BusinessError } from '@kit.BasicServicesKit'; +import { CommonConstants } from '../constants/CommonConstants'; +import { BreakpointTypeEnum } from '../utils/BreakpointSystem'; @Component export struct ProductList { private productData: ProductDataSource = new ProductDataSource(); - @StorageLink('currentBreakpoint') curBp: string = StackConstant.BREAK_POINT_SM; + @StorageLink(CommonConstants.KEY_PREFIX + 'currentBreakpoint') curBp: string = BreakpointTypeEnum.SM; aboutToAppear() { this.productData.pushData(PRODUCT_DATA); @@ -32,7 +32,7 @@ export struct ProductList { @Builder waterFlowComponent(item: ProductDataModel) { - Column({ space: StackConstant.COLUMN_SPACE }) { + Column({ space: CommonConstants.COLUMN_SPACE }) { Image(item.uri) .width($r('app.integer.icon_view_image_width')) .aspectRatio(1) @@ -42,15 +42,15 @@ export struct ProductList { .padding({ right: $r('app.integer.icon_view_padding_right') }) Text(item.title) - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .fontSize($r('app.integer.water_flow_title_font_size')) .fontWeight(FontWeight.Bold) .fontColor($r('sys.color.font_primary')) Text(item.price) - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .fontSize($r('app.integer.water_flow_price_font_size')) - .offset({ x: StackConstant.OFFSET }) + .offset({ x: CommonConstants.OFFSET }) .fontWeight(FontWeight.Bold) .fontColor($r('app.color.ohos_id_color_warning')) @@ -70,13 +70,13 @@ export struct ProductList { } .alignItems(HorizontalAlign.Start) .padding({ left: $r('app.integer.water_flow_column_padding_left') }) - .width(StackConstant.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) .height($r('app.integer.water_flow_column_height')) .backgroundColor($r('sys.color.comp_background_primary')) .borderRadius($r('app.integer.water_flow_column_border_radius')) .onClick(() => { try { - promptAction.showToast({ message: $r('app.string.component_stack_other_function') }); + this.getUIContext().getPromptAction().showToast({ message: $r('app.string.component_stack_other_function') }); } catch (error) { const err = error as BusinessError; hilog.error(0x000, 'ProductList', `showToast catch error, code: ${err.code}, message: ${err.message}`); @@ -98,8 +98,8 @@ export struct ProductList { scrollBackward: NestedScrollMode.SELF_FIRST }) .columnsTemplate(this.curBp === 'sm' ? '1fr 1fr' : this.curBp === 'md' ? '1fr 1fr 1fr' : '1fr 1fr 1fr 1fr') - .columnsGap(StackConstant.COLUMNS_GAP) - .rowsGap(StackConstant.ROWS_GAP) + .columnsGap(CommonConstants.COLUMNS_GAP) + .rowsGap(CommonConstants.ROWS_GAP) .padding({ bottom: $r('app.integer.water_flow_padding_bottom') }) } } \ No newline at end of file diff --git a/componentstacklibrary/src/main/resources/base/element/color.json b/componentstacklibrary/src/main/resources/base/element/color.json index 0fd74c846f9e5b1e69db123e65b4c23da6e2fea8..c828f7eb6f5f725019959bbbe70a66a2020cb7f4 100644 --- a/componentstacklibrary/src/main/resources/base/element/color.json +++ b/componentstacklibrary/src/main/resources/base/element/color.json @@ -1,9 +1,5 @@ { "color": [ - { - "name": "start_window_background", - "value": "#FFFFFF" - }, { "name": "ohos_id_color_list_alert", "value": "#ED6F21" diff --git a/componentstacklibrary/src/main/resources/base/element/string.json b/componentstacklibrary/src/main/resources/base/element/string.json index c36707076e3f98e8cee3335b49c219b41e8197ca..bc32604f2a0bda23aa4a0b7b22dd06d6a78e4a4c 100644 --- a/componentstacklibrary/src/main/resources/base/element/string.json +++ b/componentstacklibrary/src/main/resources/base/element/string.json @@ -1,21 +1,5 @@ { "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "组件堆叠" - }, - { - "name": "product_title00", - "value": "充电宝" - }, { "name": "product_title01", "value": "笔记本电脑" diff --git a/componentstacklibrary/src/main/resources/base/profile/main_pages.json b/componentstacklibrary/src/main/resources/base/profile/main_pages.json index 3b90675a096f4751cfea212a5149a95cf757644e..0d0d096ee9519dc07b021eacd063ed6dc797345b 100644 --- a/componentstacklibrary/src/main/resources/base/profile/main_pages.json +++ b/componentstacklibrary/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,5 @@ { "src": [ - "pages/ComponentStackPage" + "component/ComponentStackComponent" ] } diff --git a/componentstacklibrary/src/main/resources/en_US/element/string.json b/componentstacklibrary/src/main/resources/en_US/element/string.json index a117d4a59ea1ebc19513a9b476ad5c121ecbe820..f3cda33454dbb0d5df8eb11804a5aa84490f3d5d 100644 --- a/componentstacklibrary/src/main/resources/en_US/element/string.json +++ b/componentstacklibrary/src/main/resources/en_US/element/string.json @@ -1,21 +1,5 @@ { "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "Component stacking" - }, - { - "name": "product_title00", - "value": "powerbank" - }, { "name": "product_title01", "value": "laptop" diff --git a/componentstacklibrary/src/main/resources/zh_CN/element/string.json b/componentstacklibrary/src/main/resources/zh_CN/element/string.json index c36707076e3f98e8cee3335b49c219b41e8197ca..bc32604f2a0bda23aa4a0b7b22dd06d6a78e4a4c 100644 --- a/componentstacklibrary/src/main/resources/zh_CN/element/string.json +++ b/componentstacklibrary/src/main/resources/zh_CN/element/string.json @@ -1,21 +1,5 @@ { "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "组件堆叠" - }, - { - "name": "product_title00", - "value": "充电宝" - }, { "name": "product_title01", "value": "笔记本电脑" diff --git a/componentstacksample/src/main/ets/entryability/EntryAbility.ets b/componentstacksample/src/main/ets/entryability/EntryAbility.ets index d5835928e2338fc8e18fdc091ba6c3c8edf2b91f..3b0c2e1f058fec2d6df89eb2a9bb3b7b582511e3 100644 --- a/componentstacksample/src/main/ets/entryability/EntryAbility.ets +++ b/componentstacksample/src/main/ets/entryability/EntryAbility.ets @@ -13,10 +13,10 @@ * limitations under the License. */ -import { Configuration, ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; +import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; -import { window } from '@kit.ArkUI'; -import { WindowUtil } from 'componentstacklibrary'; +import { window } from '@kit.ArkUI'; +import { ComponentStackController } from 'componentstacklibrary'; const TAG = '[EntryAbility]'; @@ -24,29 +24,22 @@ export default class EntryAbility extends UIAbility { onCreate(): void { hilog.info(0x0000, TAG, '%{public}s', 'Ability onCreate'); - AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode); - this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + ComponentStackController.updatedColorMode(this.context); } onDestroy(): void { hilog.info(0x0000, TAG, '%{public}s', 'Ability onDestroy'); } - onConfigurationUpdate(newConfig: Configuration): void { - WindowUtil.updatedColorMode(newConfig) - } - onWindowStageCreate(windowStage: window.WindowStage): void { // Main window is created, set main page for this ability. hilog.info(0x0000, TAG, '%{public}s', 'Ability onWindowStageCreate'); - WindowUtil.requestFullScreen(windowStage) - WindowUtil.registerBreakPoint(windowStage) - windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, TAG, `Failed to load the content, err code: ${err.code}, message: ${err.message}`); return; } + ComponentStackController.initWindowConfig(windowStage); hilog.info(0x0000, TAG, 'Succeeded in loading the content.'); }); } diff --git a/componentstacksample/src/main/ets/pages/Index.ets b/componentstacksample/src/main/ets/pages/Index.ets index 8be4f1c80db6ab68b0a3616cf39b3d78f29b1637..5e02c9768f9635fcdc7c34d211749a1ea8153b2c 100644 --- a/componentstacksample/src/main/ets/pages/Index.ets +++ b/componentstacksample/src/main/ets/pages/Index.ets @@ -13,14 +13,14 @@ * limitations under the License. */ -import { ComponentStackPage } from 'componentstacklibrary' +import { ComponentStackComponent } from 'componentstacklibrary' @Entry @Component struct Index { build() { Stack(){ - ComponentStackPage() + ComponentStackComponent() } } } \ No newline at end of file diff --git a/componentstacksample/src/main/module.json5 b/componentstacksample/src/main/module.json5 index f3d8c7c41b0aded6e90fbc4e568843fd2f1603ee..3342dca563a251e1685673eea52c8726af529c0f 100644 --- a/componentstacksample/src/main/module.json5 +++ b/componentstacksample/src/main/module.json5 @@ -9,7 +9,7 @@ "tablet", "2in1" ], - "deliveryWithInstall": true, + "deliveryWithInstall": false, "installationFree": false, "pages": "$profile:main_pages", "abilities": [ diff --git a/componentstacksample/src/main/resources/base/element/color.json b/componentstacksample/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/componentstacksample/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/componentstacksample/src/main/resources/base/element/string.json b/componentstacksample/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9c081979c5167a04d0265fbdd5dcac64a7c0b243 --- /dev/null +++ b/componentstacksample/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "组件堆叠" + }, + { + "name": "product_title00", + "value": "充电宝" + } + ] +} \ No newline at end of file diff --git a/componentstacklibrary/src/main/resources/base/media/background.png b/componentstacksample/src/main/resources/base/media/background.png similarity index 100% rename from componentstacklibrary/src/main/resources/base/media/background.png rename to componentstacksample/src/main/resources/base/media/background.png diff --git a/componentstacklibrary/src/main/resources/base/media/foreground.png b/componentstacksample/src/main/resources/base/media/foreground.png similarity index 100% rename from componentstacklibrary/src/main/resources/base/media/foreground.png rename to componentstacksample/src/main/resources/base/media/foreground.png diff --git a/componentstacklibrary/src/main/resources/base/media/layered_image.json b/componentstacksample/src/main/resources/base/media/layered_image.json similarity index 100% rename from componentstacklibrary/src/main/resources/base/media/layered_image.json rename to componentstacksample/src/main/resources/base/media/layered_image.json diff --git a/componentstacklibrary/src/main/resources/base/media/startIcon.png b/componentstacksample/src/main/resources/base/media/startIcon.png similarity index 100% rename from componentstacklibrary/src/main/resources/base/media/startIcon.png rename to componentstacksample/src/main/resources/base/media/startIcon.png diff --git a/componentstacksample/src/main/resources/en_US/element/string.json b/componentstacksample/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3ddc584e6a68ab7b0b7fd680068a0c227f49b2bd --- /dev/null +++ b/componentstacksample/src/main/resources/en_US/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "Component stacking" + }, + { + "name": "product_title00", + "value": "powerbank" + } + ] +} \ No newline at end of file diff --git a/componentstacksample/src/main/resources/zh_CN/element/string.json b/componentstacksample/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9c081979c5167a04d0265fbdd5dcac64a7c0b243 --- /dev/null +++ b/componentstacksample/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "组件堆叠" + }, + { + "name": "product_title00", + "value": "充电宝" + } + ] +} \ No newline at end of file