diff --git a/entry/src/main/ets/home/common/BreakpointConstants.ets b/entry/src/main/ets/home/common/BreakpointConstants.ets new file mode 100644 index 0000000..ba7f91c --- /dev/null +++ b/entry/src/main/ets/home/common/BreakpointConstants.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Constants for breakpoint. + */ +export class BreakpointConstants { + /** + * Breakpoints that represent small device types. + */ + static readonly BREAKPOINT_SM: string = 'sm'; + /** + * Breakpoints that represent middle device types. + */ + static readonly BREAKPOINT_MD: string = 'md'; + /** + * Breakpoints that represent large device types. + */ + static readonly BREAKPOINT_LG: string = 'lg'; + /** + * Grid row column list. + */ + static readonly GRID_ROW_COLUMNS: number[] = [12, 15, 4]; + /** + * Grid column span list. + */ + static readonly GRID_COLUMN_SPANS: number[] = [12, 6, 7, 5, 3, 4, 2]; + /** + * Breakpoint ranges. + */ + static readonly BREAKPOINT_RANGES: number[] = [320, 600, 840]; +} \ No newline at end of file diff --git a/entry/src/main/ets/home/common/CommonConstants.ets b/entry/src/main/ets/home/common/CommonConstants.ets new file mode 100644 index 0000000..31afa29 --- /dev/null +++ b/entry/src/main/ets/home/common/CommonConstants.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Common constants for common component. + */ +export class CommonConstants { + static readonly HARMONY_HEI_TI_FONT_FAMILY = 'HarmonyHeiTi'; + static readonly FULL_PERCENT: string = '100%'; + static readonly WINDOW_UTIL: string = 'windowUtil'; + /** + * Font weight 500. + */ + static readonly FONT_WEIGHT_500: number = 500; + /** + * Device types. + */ + static readonly DEVICE_TYPES: string[] = ['2in1', 'tablet', 'phone']; +} \ No newline at end of file diff --git a/entry/src/main/ets/home/common/CommonEnums.ets b/entry/src/main/ets/home/common/CommonEnums.ets new file mode 100644 index 0000000..ce7916b --- /dev/null +++ b/entry/src/main/ets/home/common/CommonEnums.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 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 enum LoadingStatus { + OFF = 'off', + LOADING = 'loading', + SUCCESS = 'success', + FAILED = 'failed' +} \ No newline at end of file diff --git a/entry/src/main/ets/home/common/ModuleTitleComponent.ets b/entry/src/main/ets/home/common/ModuleTitleComponent.ets new file mode 100644 index 0000000..411aa31 --- /dev/null +++ b/entry/src/main/ets/home/common/ModuleTitleComponent.ets @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from './BreakpointConstants'; +import { CommonConstants } from './CommonConstants'; + +@Component +export struct ModuleTitleComponent { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_LG; + public title: string = ''; + public moduleRedirectContent: string = ''; + @Consume('appPathStack') appPathStack: NavPathStack; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + if (this.title.length) { + Row() { + Text(this.title) + .fontSize($r('app.integer.subtitle_text_L')) + .fontWeight(FontWeight.Bold) + .fontColor($r('app.color.font_primary')) + + Text(this.moduleRedirectContent) + .fontColor($r('app.color.font_secondary')) + .fontSize($r('app.integer.body_text_S')) + .fontWeight(FontWeight.Medium) + .onClick(() => { + this.jump() + }) + + } + .width(CommonConstants.FULL_PERCENT) + .height("44vp") + .justifyContent(FlexAlign.SpaceBetween) + .borderRadius($r('sys.float.corner_radius_level8')) + } + } +} diff --git a/entry/src/main/ets/home/common/ModuleTitleComponentWithIcon.ets b/entry/src/main/ets/home/common/ModuleTitleComponentWithIcon.ets new file mode 100644 index 0000000..7b3bf9f --- /dev/null +++ b/entry/src/main/ets/home/common/ModuleTitleComponentWithIcon.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from './BreakpointConstants'; +import { CommonConstants } from './CommonConstants'; + +@Component +export struct ModuleTitleComponentWithIcon { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = BreakpointConstants.BREAKPOINT_LG; + public moduleIcon: Resource = $r("app.media.icon"); + public title: string = ''; + public moduleRedirectContent: string = ''; + @Consume('appPathStack') appPathStack: NavPathStack; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + Row() { + Row() { + Image(this.moduleIcon) + .height('20vp') + .width('20vp') + .margin({ + right: "4vp" + }) + Text(this.title) + .fontSize("16fp") + .fontWeight(CommonConstants.FONT_WEIGHT_500) + .fontColor($r('sys.color.font_primary')) + } + + Text(this.moduleRedirectContent) + .fontColor(Color.Gray) + .fontSize('12fp') + .fontWeight(CommonConstants.FONT_WEIGHT_500) + .onClick(() => { + this.jump() + }) + .margin({ + right: "4vp" + }) + } + .width(CommonConstants.FULL_PERCENT) + .padding({ left: 6, right: 6 }) + .height("30vp") + .justifyContent(FlexAlign.SpaceBetween) + .borderRadius($r('sys.float.corner_radius_level6')) + } +} diff --git a/entry/src/main/ets/home/entryability/EntryAbility.ets b/entry/src/main/ets/home/entryability/EntryAbility.ets new file mode 100644 index 0000000..ff6eeea --- /dev/null +++ b/entry/src/main/ets/home/entryability/EntryAbility.ets @@ -0,0 +1,100 @@ +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; +import { WindowUtil } from '../util/WindowUtil'; + +export default class EntryAbility extends UIAbility { + private windowObj?: window.Window; + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.getMainWindow().then((data: window.Window) => { + this.windowObj = data; + this.updateWidthBp(); + this.updateHeightBp(); + this.windowObj.on('windowSizeChange', (windowSize: window.Size) => { + this.updateWidthBp(); + this.updateHeightBp(); + }) + }) + + let windowUtil: WindowUtil | undefined = WindowUtil.getInstance(); + if (windowUtil !== undefined) { + windowUtil.setWindowStage(windowStage); + windowUtil.setMainWindowPortrait(); + } + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + private updateWidthBp(): void { + if (this.windowObj === undefined) { + return; + } + let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties(); + let windowWidth: number = mainWindow.windowRect.width; + let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels; + let widthBp: string = ''; + if (windowWidthVp < 320) { + widthBp = 'xs'; + } else if (windowWidthVp >= 320 && windowWidthVp < 600) { + widthBp = 'sm'; + } else if (windowWidthVp >= 600 && windowWidthVp < 840) { + widthBp = 'md'; + } else if (windowWidthVp >= 840 && windowWidthVp < 1440) { + widthBp = 'lg'; + } else { + widthBp = 'xl'; + } + AppStorage.setOrCreate('currentWidthBreakpoint', widthBp); + } + + private updateHeightBp(): void { + if (this.windowObj === undefined) { + return; + } + let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties(); + let windowHeight: number = mainWindow.windowRect.height; + let windowWidth: number = mainWindow.windowRect.width; + let heightBp: string = ''; + let aspectRatio: number = windowHeight / windowWidth; + if (aspectRatio < 0.8) { + heightBp = 'sm'; + } else if (aspectRatio >= 0.8 && aspectRatio < 1.2) { + heightBp = 'md'; + } else { + heightBp = 'lg'; + } + AppStorage.setOrCreate('currentHeightBreakpoint', heightBp); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/entry/src/main/ets/home/util/BreakpointType.ets b/entry/src/main/ets/home/util/BreakpointType.ets new file mode 100644 index 0000000..6f55250 --- /dev/null +++ b/entry/src/main/ets/home/util/BreakpointType.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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 { BreakpointConstants } from "../common/BreakpointConstants"; + +export class BreakpointType { + sm: T; + md: T; + lg: T; + + constructor(sm: T, md: T, lg: T) { + this.sm = sm; + this.md = md; + this.lg = lg; + } + + getValue(currentWidthBreakpoint: string): T { + if (currentWidthBreakpoint === BreakpointConstants.BREAKPOINT_MD) { + return this.md; + } + if (currentWidthBreakpoint === BreakpointConstants.BREAKPOINT_LG) { + return this.lg; + } else { + return this.sm; + } + } +} \ No newline at end of file diff --git a/entry/src/main/ets/home/util/LazyDataSource.ets b/entry/src/main/ets/home/util/LazyDataSource.ets new file mode 100644 index 0000000..d8561b3 --- /dev/null +++ b/entry/src/main/ets/home/util/LazyDataSource.ets @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 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 Logger from './Logger'; +import { ObservedArray } from './ObservedArray'; + +const TAG = '[BasicDataSource]'; + +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): T | undefined { + return undefined; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + Logger.info(TAG, 'add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + Logger.info(TAG, 'remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +@Observed +export default class LazyDataSource extends BasicDataSource { + dataArray: T[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): T { + return this.dataArray[index]; + } + + public addData(index: number, data: T): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: T): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } + + public pushArrayData(newData: ObservedArray): void { + this.clear(); + this.dataArray.push(...newData); + this.notifyDataReload(); + } + + public appendArrayData(addData: ObservedArray): void { + this.dataArray.push(...addData); + this.notifyDataReload(); + } + + public deleteData(index: number): void { + this.dataArray.splice(index, 1); + this.notifyDataDelete(index); + } + + public getDataList(): ObservedArray { + return this.dataArray; + } + + public clear(): void { + this.dataArray.splice(0, this.dataArray?.length); + } + + public isEmpty(): boolean { + return this.dataArray.length === 0; + } +} diff --git a/entry/src/main/ets/home/util/Logger.ets b/entry/src/main/ets/home/util/Logger.ets new file mode 100644 index 0000000..75d04e2 --- /dev/null +++ b/entry/src/main/ets/home/util/Logger.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 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'; + +class Logger { + private domain: number; + private prefix: string; + private format: string = "%{public}s, %{public}s"; + + constructor(prefix: string) { + this.prefix = prefix; + this.domain = 0xFF00; + } + + debug(...args: Object[]): void { + hilog.debug(this.domain, this.prefix, this.format, args); + } + + info(...args: Object[]): void { + hilog.info(this.domain, this.prefix, this.format, args); + } + + warn(...args: Object[]): void { + hilog.warn(this.domain, this.prefix, this.format, args); + } + + error(...args: Object[]): void { + hilog.error(this.domain, this.prefix, this.format, args); + } +} + +export default new Logger('[HMOSWorld]'); diff --git a/entry/src/main/ets/home/util/ObservedArray.ets b/entry/src/main/ets/home/util/ObservedArray.ets new file mode 100644 index 0000000..921097b --- /dev/null +++ b/entry/src/main/ets/home/util/ObservedArray.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + +/** + * Wraps an array as an observed object + */ +@Observed +export class ObservedArray extends Array { + constructor(args?: T[]) { + if (args instanceof Array) { + super(...args); + } else { + super(); + } + } +} diff --git a/entry/src/main/ets/home/util/WebUtils.ets b/entry/src/main/ets/home/util/WebUtils.ets new file mode 100644 index 0000000..9fe4a4b --- /dev/null +++ b/entry/src/main/ets/home/util/WebUtils.ets @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 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 { BuilderNode, FrameNode, NodeController, Size } from '@kit.ArkUI'; +import { webview } from '@kit.ArkWeb'; +import { CommonConstants } from '../common/CommonConstants'; +import Logger from './Logger'; + +let nodeMap: Map = new Map(); +let controllerMap: Map = new Map(); +let onPageEndMap: Map = new Map(); +let onProgressChangeMap: Map = new Map(); +let onResourceLoadMap: Map = new Map(); +let context: UIContext; + +class Data { + public url: string; + public controller: WebviewController; + public onPageEndAction?: Function; + public onProgressChangeAction?: Function; + public onResourceLoadAction?: Function; + + constructor(url: string, controller: WebviewController) { + this.url = url; + this.controller = controller; + } +} + +// Developer-defined template +@Builder +function webBuilder(data: Data) { + Web({ src: data.url.split('~')[0], controller: data.controller }) + .domStorageAccess(true) + .zoomAccess(true) + .fileAccess(true) + .mixedMode(MixedMode.All) + .cacheMode(CacheMode.Default) + .verticalScrollBarAccess(false) + .javaScriptAccess(true) + .pinchSmooth(true) + .onFirstContentfulPaint(() => { + nodeMap.set('hmos_' + data.url, undefined); + }) + .onPageEnd(() => { + onPageEndMap.get(data.url)?.(); + }) + .onProgressChange((event) => { + Logger.info('newProgress:' + event?.newProgress); + if (event?.newProgress === 100) { + onProgressChangeMap.get(data.url)?.(); + } + Logger.info('onProgressChange weburl: ' + data.url); + }) + .onResourceLoad((event) => { + Logger.info('onResourceLoad:' + event?.url); + onResourceLoadMap.get(data.url)?.(event.url); + }) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) +} + +let wrap = wrapBuilder(webBuilder); + +/** + * Controls and feeds back the behavior of the node on the corresponding NodeContainer. + * It must be used together with NodeContainer. + */ +export class MyNodeController extends NodeController { + private rootNode: BuilderNode | null | undefined = null; + private isRemove: boolean = false; + + // Used to construct the number of nodes and return the node mount in the corresponding NodeContainer. + // This API is called when the corresponding NodeContainer is created or by using the rebuild method. + makeNode(uiContext: UIContext): FrameNode | null { + Logger.info('uiContext is undifined : ' + (uiContext === undefined)); + if (this.isRemove) { + return null; + } + if (this.rootNode != undefined) { + return this.rootNode.getFrameNode(); + } + return null; + } + + disposeNode() { + this.rootNode?.dispose(); + } + + aboutToResize(size: Size) { + Logger.info('aboutToResize width : ' + size.width + ' height : ' + size.height); + } + + aboutToAppear() { + if (this.rootNode == undefined) { + return; + } + } + + aboutToDisappear() { + Logger.info('aboutToDisappear'); + } + + + initWeb(url: string, uiContext: UIContext, control: WebviewController, onPageEndAction?: Function) { + if (this.rootNode != null) { + return; + } + this.rootNode = new BuilderNode(uiContext); + this.rootNode.dispose() + this.rootNode.build(wrap, { url: url, controller: control }); + } +} + +export function createNWeb(url: string, uiContext?: UIContext) { + if (nodeMap.has(url)) { + return; + } + if (!context && uiContext) { + context = uiContext; + } + let baseNode = new MyNodeController(); + let controller = new webview.WebviewController(); + baseNode.initWeb(url, context, controller); + controllerMap.set(url, controller) + nodeMap.set(url, baseNode); +} + +export const getNWeb = (url: string): MyNodeController | undefined => { + return nodeMap.get(url); +} + +// Destruct the created node. +export const deleteNode = (url: string) => { + let nodeController = nodeMap.get(url); + nodeController?.disposeNode(); + nodeMap.delete(url); + controllerMap.delete(url); + onPageEndMap.delete(url); +} \ No newline at end of file diff --git a/entry/src/main/ets/home/util/WindowUtil.ets b/entry/src/main/ets/home/util/WindowUtil.ets new file mode 100644 index 0000000..f090cdf --- /dev/null +++ b/entry/src/main/ets/home/util/WindowUtil.ets @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 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 { deviceInfo } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; +import Logger from './Logger'; +import { CommonConstants } from '../common/CommonConstants'; + +@Observed +export class WindowUtil { + private windowStage?: window.WindowStage; + private mainWindowClass?: window.Window; + + static getInstance(): WindowUtil | undefined { + if (!AppStorage.get(CommonConstants.WINDOW_UTIL)) { + AppStorage.setOrCreate(CommonConstants.WINDOW_UTIL, new WindowUtil()); + } else { + Logger.info(`AppStorage does not have windowUtil`); + } + return AppStorage.get(CommonConstants.WINDOW_UTIL); + } + + setWindowStage(windowStage: window.WindowStage): void { + this.windowStage = windowStage; + } + + setMainWindowPortrait(): void { + if (this.windowStage === undefined) { + Logger.error(`WindowStage is undefined`); + return; + } + this.windowStage.getMainWindow((err, windowClass: window.Window) => { + this.mainWindowClass = windowClass; + if (err.code) { + Logger.error(`Failed to obtain the main window. Code:${err.code}, message:${err.message}`); + return; + } + if (deviceInfo.deviceType !== CommonConstants.DEVICE_TYPES[0] && deviceInfo.deviceType !== + CommonConstants.DEVICE_TYPES[1]) { + this.mainWindowClass.setPreferredOrientation(window.Orientation.PORTRAIT); + } + }); + } + + setMainWindowOrientation(orientation: window.Orientation): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setPreferredOrientation(orientation); + } + + disableWindowSystemBar(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowSystemBarEnable([]); + } + + enableWindowSystemBar(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowSystemBarEnable(['status', 'navigation']); + } + + setFullScreen(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass.setWindowLayoutFullScreen(true); + } + + getMainWindow(): window.Window | undefined { + return this.mainWindowClass; + } + + offWindowSizeChange(): void { + if (this.mainWindowClass === undefined) { + Logger.error(`MainWindowClass is undefined`); + return; + } + this.mainWindowClass?.off('windowSizeChange'); + } +} \ No newline at end of file diff --git a/entry/src/main/ets/home/view/EmptyPagePathStack.ets b/entry/src/main/ets/home/view/EmptyPagePathStack.ets new file mode 100644 index 0000000..692fc56 --- /dev/null +++ b/entry/src/main/ets/home/view/EmptyPagePathStack.ets @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 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 { CommonConstants } from '../common/CommonConstants'; + + +@Component +export struct EmptyPagePathStack { + @Consume('appPathStack') appPathStack: NavPathStack; + + build() { + NavDestination() { + Column() { + TopNavigationView({ + title: "详情页", + onBackClick: () => { + this.appPathStack.pop(); + } + }) + Image($r("app.media.realImageGen_travel_0")) + } + .justifyContent(FlexAlign.SpaceBetween) + .alignItems(HorizontalAlign.Center) + .width(CommonConstants.FULL_PERCENT) + .height(CommonConstants.FULL_PERCENT) + } + .hideTitleBar(true) + } +} + +@Builder +export function EmptyPagePathStackBuilder() { + EmptyPagePathStack() +} + +@Component +struct TopNavigationView { + title?: ResourceStr; + onBackClick?: Function; + + build() { + Row() { + if (this.onBackClick) { + Image($r('app.media.ic_back')) + .width("40vp") + .height("40vp") + .margin({ right: "16vp" }) + .onClick(() => this.onBackClick?.()) + } + + Text(this.title) + .fontSize("20fp") + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Start) + .layoutWeight(1) + } + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .width(CommonConstants.FULL_PERCENT) + .height("56vp") + .padding({ + left: "24vp", + right: "24vp" + }) + } +} diff --git a/entry/src/main/ets/home/view/LoadingFailedView.ets b/entry/src/main/ets/home/view/LoadingFailedView.ets new file mode 100644 index 0000000..ba7ff16 --- /dev/null +++ b/entry/src/main/ets/home/view/LoadingFailedView.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 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 { CommonConstants } from '../common/CommonConstants' + +@Builder +export function LoadingFailedView(handleReload?: () => void) { + Row() { + Column() { + Image($r('app.media.ic_failure')) + .width("120vp") + .height("120vp") + Text("Failed to load the network") + .fontColor($r('sys.color.mask_secondary')) + .fontFamily(CommonConstants.HARMONY_HEI_TI_FONT_FAMILY) + .fontSize("14fp") + .margin({ top: "8vp" }) + Row() { + Text("Reload") + .fontColor("#FF3E50") + .fontFamily(CommonConstants.HARMONY_HEI_TI_FONT_FAMILY) + .fontSize("12fp") + .width(CommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Center) + } + .height("32vp") + .width("80vp") + .margin({ top: "8vp" }) + .borderRadius($r('sys.float.corner_radius_level6')) + .onClick(() => handleReload?.()) + } + } + .justifyContent(FlexAlign.Center) + .layoutWeight(1) +} \ No newline at end of file diff --git a/entry/src/main/ets/home/view/LoadingView.ets b/entry/src/main/ets/home/view/LoadingView.ets new file mode 100644 index 0000000..4716d7c --- /dev/null +++ b/entry/src/main/ets/home/view/LoadingView.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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 { CommonConstants } from '../common/CommonConstants' + +@Component +export struct LoadingView { + build() { + Column() { + Row() { + LoadingProgress() + } + .margin({ top: "260vp" }) + .width("72vp") + .height("72vp") + } + .height(CommonConstants.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/home/view/Module0.ets b/entry/src/main/ets/home/view/Module0.ets new file mode 100644 index 0000000..8b9ca4b --- /dev/null +++ b/entry/src/main/ets/home/view/Module0.ets @@ -0,0 +1,45 @@ +@Component +export struct Module0 { + build() { + Column() { + Row() { + Text('健康') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .margin(30) + Blank() + } + .width('100%') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + + Grid() { + GridItem() { + } + .padding({ + top: 5, + left: 3, + bottom: 5, + right: 3 + }) + } + .backgroundColor('#FFFFFF') + .width('95%') + .borderRadius(20) + .margin({ bottom: 10 }) + .clip(true) + .maxCount(1) + .alignSelf(ItemAlign.Center) + } + .width('100%') + .alignItems(HorizontalAlign.Center) + .backgroundColor('#FFFFFF') + .margin({ bottom: 10 }) + .clip(true) + .constraintSize({ minHeight: ' 15.07%' }) + .backgroundColor('#FFFFFF') + } +} diff --git a/entry/src/main/ets/home/view/Module1.ets b/entry/src/main/ets/home/view/Module1.ets new file mode 100644 index 0000000..e881bb0 --- /dev/null +++ b/entry/src/main/ets/home/view/Module1.ets @@ -0,0 +1,253 @@ +@Component +export struct Module1 { + build() { + Column() { + Row() { + Column() { + Text('卡路里') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('117') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('/500千卡') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + .layoutWeight(1) + + Blank() + Column() { + Text('步数') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('1889') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('/8000步') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + .layoutWeight(1) + + Blank() + Column() { + Text('中高强度') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('13') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('/30分钟') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + .layoutWeight(1) + } + .width('100%') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .padding({ top: '10.0px', bottom: '10.0px' }) + + Row() { + Column() { + Text('活动次数 4 次') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + .layoutWeight(1) + + Blank() + Column() { + Text('睡眠') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('8时27分') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('12月23日 睡眠质量良好') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('有待提高') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + .layoutWeight(1) + } + .width('100%') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .padding({ top: '10.0px', bottom: '10.0px' }) + + Grid() { + GridItem() { + Column() { + Text('心率') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('96次/分') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('12月23日 16:29') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + } + .padding({ + top: 5, + left: 3, + bottom: 5, + right: 3 + }) + + GridItem() { + Column() { + Text('血氧饱和度') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('97%') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('12月23日 16:29') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + } + .padding({ + top: 5, + left: 3, + bottom: 5, + right: 3 + }) + + GridItem() { + Column() { + Text('体重') + .maxFontSize(14) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('58.50KG') + .maxFontSize(20) + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + Text('9月11日 16:12') + .maxFontSize(12) + .fontColor('#888888') + .margin(2) + .minFontSize(8) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + } + .alignItems(HorizontalAlign.Center) + .padding({ left: '10.0px', right: '10.0px' }) + } + .padding({ + top: 5, + left: 3, + bottom: 5, + right: 3 + }) + } + .borderRadius(20) + .backgroundColor('#ffffff') + .width('95%') + .margin({ bottom: 10 }) + .clip(true) + .columnsTemplate(('1fr ').repeat(2)) + .maxCount(3) + .alignSelf(ItemAlign.Center) + } + .width('95%') + .borderRadius(20) + .backgroundColor('#ffffff') + .alignItems(HorizontalAlign.Center) + .padding({ top: '10.0px', bottom: '10.0px' }) + .margin({ bottom: 10 }) + .clip(true) + } +} diff --git a/entry/src/main/ets/home/view/SearchModuleWithButtonPage.ets b/entry/src/main/ets/home/view/SearchModuleWithButtonPage.ets new file mode 100644 index 0000000..66dc090 --- /dev/null +++ b/entry/src/main/ets/home/view/SearchModuleWithButtonPage.ets @@ -0,0 +1,98 @@ +/* + * 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. + */ + +/* + * 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 { curves } from '@kit.ArkUI'; +import { CommonConstants } from '../common/CommonConstants'; + +@Builder +export function SearchModuleWithButtonPageBuilder() { + SearchModuleWithButtonPage() +} + +@Component +export default struct SearchModuleWithButtonPage { + private pageInfos: NavPathStack = new NavPathStack(); + + private onArrowClicked(): void { + this.pageInfos.pop(false); + } + + build() { + NavDestination() { + Row() { + Image($r('app.media.icon')) + .width(40) + .height(40) + .onClick(() => { + this.onArrowClicked(); + }) + Search({ placeholder: '搜索交通/酒店/景点等' }) + .searchButton('搜索') + .enableKeyboardOnFocus(false) + .placeholderColor(Color.Black) + .placeholderFont({ + family: "HarmonyHeiTi", + size: 16, + weight: 400 + }) + .borderColor($r('sys.color.font_primary')) + .searchIcon({ color: Color.Black }) + .backgroundColor(Color.White) + .defaultFocus(true) + .focusOnTouch(true) + .fontColor(Color.Black) + .width('85%') + .padding({ + left: "24vp", + right: "24vp" + }) + } + .width(CommonConstants.FULL_PERCENT) + .height(50) + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .margin({ bottom: '10vp' }) + } + .transition(TransitionEffect.OPACITY) + .hideTitleBar(true) + .backgroundColor('#F1F3F5') + .onReady((context: NavDestinationContext) => { + this.pageInfos = context.pathStack; + }) + .onBackPressed(() => { + animateTo({ + curve: curves.interpolatingSpring(0, 1, 342, 38), + }, () => { + this.pageInfos.pop(false); + }) + return true; + }) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/home/view/SecondPageSearch.ets b/entry/src/main/ets/home/view/SecondPageSearch.ets new file mode 100644 index 0000000..860a0fe --- /dev/null +++ b/entry/src/main/ets/home/view/SecondPageSearch.ets @@ -0,0 +1,107 @@ +/* + * 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 { CommonConstants } from '../common/CommonConstants'; + + +@Component +export struct SecondPageSearch { + @Consume('appPathStack') appPathStack: NavPathStack; + @State searchValue: string = ''; + + jump(): void { + this.appPathStack.pushPathByName('EmptyPagePathStack', null); + } + + build() { + NavDestination() { + Column() { + SearchBar({ + searchValue: this.searchValue, + onBack: () => { + this.appPathStack.clear(); + return false; + } + }) + } + .backgroundColor($r('sys.color.ohos_id_color_sub_background')) + .height(CommonConstants.FULL_PERCENT) + .width(CommonConstants.FULL_PERCENT) + } + .hideTitleBar(true) + .onBackPressed(() => { + this.appPathStack.clear(); + return true; + }) + } +} + +@Builder +export function SearchPageBuilder() { + SecondPageSearch() +} + +@Component +struct SearchBar { + @Consume('appPathStack') appPathStack: NavPathStack; + @Link searchValue: string; + onBack: () => void = () => { + }; + + build() { + Row() { + Image($r('app.media.ic_back')) + .size({ width: "24vp", height: "24vp" }) + .width("40vp") + .height("40vp") + .margin({ right: "8vp" }) + .onClick(() => this.onBack()) + + SearchInput({ + searchValue: this.searchValue + }) + } + .width(CommonConstants.FULL_PERCENT) + .padding({ + top: "8vp", + bottom: "8vp", + left: "24vp", + right: "24vp" + }) + } +} + +@Component +struct SearchInput { + @Link searchValue: string; + + aboutToAppear(): void { + } + + aboutToDisappear(): void { + } + + build() { + Search({ + placeholder: "Search", + value: this.searchValue + }) + .enableKeyboardOnFocus(true) + .textFont({ size: "16fp" }) + .placeholderFont({ size: "16fp" }) + .height("40vp") + .layoutWeight(1) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/Hello.ets b/entry/src/main/ets/pages/Hello.ets new file mode 100644 index 0000000..7cad5d0 --- /dev/null +++ b/entry/src/main/ets/pages/Hello.ets @@ -0,0 +1,42 @@ +@Entry +@Component +struct Hello { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.message = 'Welcome'; + }) + Button() { + Text('Next') + .fontSize(30) + .fontWeight(FontWeight.Bold) + } + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('40%') + .height('5%') + .onClick(() => { + console.log("用户操作:点击按钮") + let uiContext: UIContext = this.getUIContext(); + let router = uiContext.getRouter(); + router.pushUrl({ + url: 'pages/Second' + }).then(() => { + console.log('系统提示:跳转成功') + }) + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index a745e49..a90bd63 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -1,42 +1,24 @@ +import { Module0 } from '../home/view/Module0'; +import { Module1 } from '../home/view/Module1'; + @Entry @Component struct Index { - @State message: string = 'Hello World'; + private scroller: Scroller = new Scroller(); build() { - Row() { + Scroll(this.scroller) { Column() { - Text(this.message) - .fontSize($r('app.float.page_text_font_size')) - .fontWeight(FontWeight.Bold) - .onClick(() => { - this.message = 'Welcome'; - }) - Button() { - Text('Next') - .fontSize(30) - .fontWeight(FontWeight.Bold) - } - .type(ButtonType.Capsule) - .margin({ - top: 20 - }) - .backgroundColor('#0D9FFB') - .width('40%') - .height('5%') - .onClick(() => { - console.log("用户操作:点击按钮") - let uiContext: UIContext = this.getUIContext(); - let router = uiContext.getRouter(); - router.pushUrl({ - url: 'pages/Second' - }).then(() => { - console.log('系统提示:跳转成功') - }) - }) + Module0() + Module1() } .width('100%') } + .scrollable(ScrollDirection.Vertical) + .scrollBar(BarState.Off) + .width('100%') .height('100%') + .align(Alignment.Top) + .backgroundColor($r('app.color.page_bg_color')) } -} \ No newline at end of file +} diff --git a/entry/src/main/ets/pages/Second.ets b/entry/src/main/ets/pages/Text.ets similarity index 100% rename from entry/src/main/ets/pages/Second.ets rename to entry/src/main/ets/pages/Text.ets diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json index 54bb950..116f185 100644 --- a/entry/src/main/resources/base/element/color.json +++ b/entry/src/main/resources/base/element/color.json @@ -1,8 +1,48 @@ { - "color": [ - { - "name": "start_window_background", - "value": "#FFFFFFFF" - } - ] + "color" : [ { + "name" : "start_window_background", + "value" : "#FFFFFFFF" + }, { + "name" : "app_icon_color", + "value" : "#BDBDBD" + }, { + "name" : "app_icon_pressed_color", + "value" : "#9E9E9E" + }, { + "name" : "page_bg_color", + "value" : "#F5F5F5" + }, { + "name" : "page_title_font_color", + "value" : "#616161" + }, { + "name" : "module_bg_color", + "value" : "#EEEEEE" + }, { + "name" : "module_title_font_color", + "value" : "#757575" + }, { + "name" : "module_icon_color", + "value" : "#9E9E9E" + }, { + "name" : "module_item_bg_color", + "value" : "#F2F2F2" + }, { + "name" : "content_main_title_font_color", + "value" : "#616161" + }, { + "name" : "content_sub_title_font_color", + "value" : "#757575" + }, { + "name" : "content_label_font_color", + "value" : "#9E9E9E" + }, { + "name" : "content_font_color", + "value" : "#000000" + }, { + "name" : "button_bg_color", + "value" : "#757575" + }, { + "name" : "button_font_color", + "value" : "#FFFFFF" + } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color_dark.json b/entry/src/main/resources/base/element/color_dark.json new file mode 100644 index 0000000..9b689d0 --- /dev/null +++ b/entry/src/main/resources/base/element/color_dark.json @@ -0,0 +1,156 @@ +{ + "color" : [ { + "name" : "brand_dark", + "value" : "#ff317af7" + }, { + "name" : "warning_dark", + "value" : "#ffd94838" + }, { + "name" : "alert_dark", + "value" : "#ffdb6b42" + }, { + "name" : "confirm_dark", + "value" : "#ff5ba854" + }, { + "name" : "font_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "font_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "font_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "font_fourth_dark", + "value" : "#33ffffff" + }, { + "name" : "font_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "font_on_primary_dark", + "value" : "#ff000000" + }, { + "name" : "font_on_secondary_dark", + "value" : "#99000000" + }, { + "name" : "font_on_tertiary_dark", + "value" : "#66000000" + }, { + "name" : "font_on_fourth_dark", + "value" : "#33000000" + }, { + "name" : "icon_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "icon_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "icon_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "icon_fourth_dark", + "value" : "#33ffffff" + }, { + "name" : "icon_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "icon_sub_emphasize_dark", + "value" : "#66317af7" + }, { + "name" : "icon_on_primary_dark", + "value" : "#ff000000" + }, { + "name" : "icon_on_secondary_dark", + "value" : "#99000000" + }, { + "name" : "icon_on_tertiary_dark", + "value" : "#66000000" + }, { + "name" : "icon_on_fourth_dark", + "value" : "#33000000" + }, { + "name" : "background_primary_dark", + "value" : "#ff000000" + }, { + "name" : "background_secondary_dark", + "value" : "#ff000000" + }, { + "name" : "background_tertiary_dark", + "value" : "#ff202224" + }, { + "name" : "background_fourth_dark", + "value" : "#ff2e3033" + }, { + "name" : "background_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "comp_foreground_primary_dark", + "value" : "#ffe5e5e5" + }, { + "name" : "comp_background_primary_dark", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_trans_dark", + "value" : "#33ffffff" + }, { + "name" : "comp_background_primary_contrary_dark", + "value" : "#ffe5e5e5" + }, { + "name" : "comp_background_gray_dark", + "value" : "#ffe5e5ea" + }, { + "name" : "comp_background_secondary_dark", + "value" : "#19ffffff" + }, { + "name" : "comp_background_tertiary_dark", + "value" : "#0cffffff" + }, { + "name" : "comp_background_emphasize_dark", + "value" : "#ff317af7" + }, { + "name" : "comp_background_neutral_dark", + "value" : "#ffffffff" + }, { + "name" : "comp_emphasize_secondary_dark", + "value" : "#33317af7" + }, { + "name" : "comp_emphasize_tertiary_dark", + "value" : "#19317af7" + }, { + "name" : "comp_divider_dark", + "value" : "#33ffffff" + }, { + "name" : "comp_common_contrary_dark", + "value" : "#ff000000" + }, { + "name" : "comp_background_focus_dark", + "value" : "#ff000000" + }, { + "name" : "comp_focused_primary_dark", + "value" : "#e5ffffff" + }, { + "name" : "comp_focused_secondary_dark", + "value" : "#99ffffff" + }, { + "name" : "comp_focused_tertiary_dark", + "value" : "#66ffffff" + }, { + "name" : "interactive_hover_dark", + "value" : "#0cffffff" + }, { + "name" : "interactive_pressed_dark", + "value" : "#19ffffff" + }, { + "name" : "interactive_focus_dark", + "value" : "#ff317af7" + }, { + "name" : "interactive_active_dark", + "value" : "#ff317af7" + }, { + "name" : "interactive_select_dark", + "value" : "#33ffffff" + }, { + "name" : "interactive_click_dark", + "value" : "#19ffffff" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color_light.json b/entry/src/main/resources/base/element/color_light.json new file mode 100644 index 0000000..33b544e --- /dev/null +++ b/entry/src/main/resources/base/element/color_light.json @@ -0,0 +1,156 @@ +{ + "color" : [ { + "name" : "brand", + "value" : "#ff0a59f7" + }, { + "name" : "warning", + "value" : "#ffe84026" + }, { + "name" : "alert", + "value" : "#ffed6f21" + }, { + "name" : "confirm", + "value" : "#ff64bb5c" + }, { + "name" : "font_primary", + "value" : "#e5000000" + }, { + "name" : "font_secondary", + "value" : "#99000000" + }, { + "name" : "font_tertiary", + "value" : "#66000000" + }, { + "name" : "font_fourth", + "value" : "#33000000" + }, { + "name" : "font_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "font_on_primary", + "value" : "#ffffffff" + }, { + "name" : "font_on_secondary", + "value" : "#99ffffff" + }, { + "name" : "font_on_tertiary", + "value" : "#66ffffff" + }, { + "name" : "font_on_fourth", + "value" : "#33ffffff" + }, { + "name" : "icon_primary", + "value" : "#e5000000" + }, { + "name" : "icon_secondary", + "value" : "#99000000" + }, { + "name" : "icon_tertiary", + "value" : "#66000000" + }, { + "name" : "icon_fourth", + "value" : "#33000000" + }, { + "name" : "icon_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "icon_sub_emphasize", + "value" : "#660a59f7" + }, { + "name" : "icon_on_primary", + "value" : "#ffffffff" + }, { + "name" : "icon_on_secondary", + "value" : "#99ffffff" + }, { + "name" : "icon_on_tertiary", + "value" : "#66ffffff" + }, { + "name" : "icon_on_fourth", + "value" : "#33ffffff" + }, { + "name" : "background_primary", + "value" : "#ffffffff" + }, { + "name" : "background_secondary", + "value" : "#fff1f3f5" + }, { + "name" : "background_tertiary", + "value" : "#ffe5e5ea" + }, { + "name" : "background_fourth", + "value" : "#ffd1d1d6" + }, { + "name" : "background_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "comp_foreground_primary", + "value" : "#ff000000" + }, { + "name" : "comp_background_primary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_trans", + "value" : "#ffffffff" + }, { + "name" : "comp_background_primary_contrary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_gray", + "value" : "#fff1f3f5" + }, { + "name" : "comp_background_secondary", + "value" : "#19000000" + }, { + "name" : "comp_background_tertiary", + "value" : "#0c000000" + }, { + "name" : "comp_background_emphasize", + "value" : "#ff0a59f7" + }, { + "name" : "comp_background_neutral", + "value" : "#ff000000" + }, { + "name" : "comp_emphasize_secondary", + "value" : "#330a59f7" + }, { + "name" : "comp_emphasize_tertiary", + "value" : "#190a59f7" + }, { + "name" : "comp_divider", + "value" : "#33000000" + }, { + "name" : "comp_common_contrary", + "value" : "#ffffffff" + }, { + "name" : "comp_background_focus", + "value" : "#fff1f3f5" + }, { + "name" : "comp_focused_primary", + "value" : "#e5000000" + }, { + "name" : "comp_focused_secondary", + "value" : "#99000000" + }, { + "name" : "comp_focused_tertiary", + "value" : "#66000000" + }, { + "name" : "interactive_hover", + "value" : "#0c000000" + }, { + "name" : "interactive_pressed", + "value" : "#19000000" + }, { + "name" : "interactive_focus", + "value" : "#ff0a59f7" + }, { + "name" : "interactive_active", + "value" : "#ff0a59f7" + }, { + "name" : "interactive_select", + "value" : "#33000000" + }, { + "name" : "interactive_click", + "value" : "#19000000" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/float.json b/entry/src/main/resources/base/element/float.json index 33ea223..658ac5a 100644 --- a/entry/src/main/resources/base/element/float.json +++ b/entry/src/main/resources/base/element/float.json @@ -1,8 +1,9 @@ { - "float": [ - { - "name": "page_text_font_size", - "value": "50fp" - } - ] -} + "float" : [ { + "name" : "font_size", + "value" : "14fp" + }, { + "name" : "page_text_font_size", + "value" : "50fp" + } ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/font_size.json b/entry/src/main/resources/base/element/font_size.json new file mode 100644 index 0000000..bf3fa77 --- /dev/null +++ b/entry/src/main/resources/base/element/font_size.json @@ -0,0 +1,63 @@ +{ + "integer" : [ { + "name" : "display_text_L", + "value" : 56, + "comment" : "Light" + }, { + "name" : "display_text_M", + "value" : 48, + "comment" : "Light" + }, { + "name" : "display_text_S", + "value" : 38, + "comment" : "Light" + }, { + "name" : "title_text_L", + "value" : 30, + "comment" : "Bold" + }, { + "name" : "title_text_M", + "value" : 24, + "comment" : "Bold" + }, { + "name" : "title_text_S", + "value" : 20, + "comment" : "Bold" + }, { + "name" : "subtitle_text_L", + "value" : 18, + "comment" : "Medium" + }, { + "name" : "subtitle_text_M", + "value" : 16, + "comment" : "Medium" + }, { + "name" : "subtitle_text_S", + "value" : 14, + "comment" : "Medium" + }, { + "name" : "body_text_L", + "value" : 16, + "comment" : "Regular" + }, { + "name" : "body_text_M", + "value" : 14, + "comment" : "Regular" + }, { + "name" : "body_text_S", + "value" : 12, + "comment" : "Regular" + }, { + "name" : "caption_text_L", + "value" : 12, + "comment" : "Medium" + }, { + "name" : "caption_text_M", + "value" : 10, + "comment" : "Medium" + }, { + "name" : "caption_text_S", + "value" : 8, + "comment" : "Medium" + } ] +} \ 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 f945955..18d85ed 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -1,16 +1,36 @@ { - "string": [ - { - "name": "module_desc", - "value": "module description" - }, - { - "name": "EntryAbility_desc", - "value": "description" - }, - { - "name": "EntryAbility_label", - "value": "label" - } - ] + "string" : [ { + "name" : "module_desc", + "value" : "module description" + }, { + "name" : "EntryAbility_desc", + "value" : "description" + }, { + "name" : "EntryAbility_label", + "value" : "label" + }, { + "name" : "defaultForm_label", + "value" : "form_label" + }, { + "name" : "defaultForm_desc", + "value" : "form_description" + }, { + "name" : "EntryFormAbility_desc", + "value" : "form_description" + }, { + "name" : "EntryFormAbility_label", + "value" : "form_label" + }, { + "name" : "widget_desc", + "value" : "This is a service widget." + }, { + "name" : "widget_display_name", + "value" : "widget" + }, { + "name" : "widget1_desc", + "value" : "This is a service widget." + }, { + "name" : "widget1_display_name", + "value" : "widget1" + } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/media/emoji_image_3_0.png b/entry/src/main/resources/base/media/emoji_image_3_0.png new file mode 100644 index 0000000..7cc0164 Binary files /dev/null and b/entry/src/main/resources/base/media/emoji_image_3_0.png differ diff --git a/entry/src/main/resources/base/media/emoji_image_3_1.png b/entry/src/main/resources/base/media/emoji_image_3_1.png new file mode 100644 index 0000000..12d4ab8 Binary files /dev/null and b/entry/src/main/resources/base/media/emoji_image_3_1.png differ diff --git a/entry/src/main/resources/base/media/emoji_image_3_2.png b/entry/src/main/resources/base/media/emoji_image_3_2.png new file mode 100644 index 0000000..56c77cc Binary files /dev/null and b/entry/src/main/resources/base/media/emoji_image_3_2.png differ diff --git a/entry/src/main/resources/base/media/ic_back.svg b/entry/src/main/resources/base/media/ic_back.svg new file mode 100644 index 0000000..a67bad0 --- /dev/null +++ b/entry/src/main/resources/base/media/ic_back.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/entry/src/main/resources/base/media/ic_failure.svg b/entry/src/main/resources/base/media/ic_failure.svg new file mode 100644 index 0000000..6d1e0c0 --- /dev/null +++ b/entry/src/main/resources/base/media/ic_failure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000..514fd95 Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ diff --git a/entry/src/main/resources/base/media/lib_icon_192.svg b/entry/src/main/resources/base/media/lib_icon_192.svg new file mode 100644 index 0000000..0797cfd --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_192.svg @@ -0,0 +1,18 @@ + + +ic_watermark_menu_sport + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/lib_icon_2.svg b/entry/src/main/resources/base/media/lib_icon_2.svg new file mode 100644 index 0000000..080a716 --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_2.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/entry/src/main/resources/base/media/lib_icon_20.svg b/entry/src/main/resources/base/media/lib_icon_20.svg new file mode 100644 index 0000000..4087ead --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_20.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/entry/src/main/resources/base/media/lib_icon_9.svg b/entry/src/main/resources/base/media/lib_icon_9.svg new file mode 100644 index 0000000..6c4deff --- /dev/null +++ b/entry/src/main/resources/base/media/lib_icon_9.svg @@ -0,0 +1,13 @@ + + + Public/ic_public_home_filled + + + + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/realImageGen_travel_0.png b/entry/src/main/resources/base/media/realImageGen_travel_0.png new file mode 100644 index 0000000..62aae9e Binary files /dev/null and b/entry/src/main/resources/base/media/realImageGen_travel_0.png differ diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index f6191bd..528157c 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -1,6 +1,6 @@ { - "src": [ - "pages/Index", - "pages/Second" + "src" : [ "pages/Index", + "pages/Hello", + "pages/Text" ] -} +} \ No newline at end of file