diff --git a/AppScope/resources/base/element/string.json b/AppScope/resources/base/element/string.json index 832bfd1f29ae1536b91590475c9043d8f69474e5..faae8ed71bba55e57bba53b93f430c923e636b45 100644 --- a/AppScope/resources/base/element/string.json +++ b/AppScope/resources/base/element/string.json @@ -2,7 +2,7 @@ "string": [ { "name": "app_name", - "value": "MultiStockCategoryApplication" + "value": "MultiTicketClass" } ] } diff --git a/AppScope/resources/base/media/foreground.png b/AppScope/resources/base/media/foreground.png index 97014d3e10e5ff511409c378cd4255713aecd85f..eb9427585b36d14b12477435b6419d1f07b3e0bb 100644 Binary files a/AppScope/resources/base/media/foreground.png and b/AppScope/resources/base/media/foreground.png differ diff --git a/README.en.md b/README.en.md index 47448f89c457ff4e3a8f755e95ef532c2abfd39a..850036544a569f6de064d1230865e31a1af8aab4 100644 --- a/README.en.md +++ b/README.en.md @@ -52,40 +52,63 @@ How to Use ## Project Directory ``` -├──entry/src/main/ets // Code area -│ ├──chartmodels -│ │ ├──BarChartView.ets // Bar chart component logic -│ │ ├──ChartAxisFormatter.ets // Line chart data formatting -│ │ └──LineChartModel.ets // Line chart component logic -│ ├──entryability -│ │ └──EntryAbility.ets // Application entry -│ ├──entrybackupability -│ │ └──EntryBackupAbility.ets // Data backup and restoration -│ ├──models -│ │ └──DataModel.ets // Stock data -│ ├──pages -│ │ ├──Index.ets // Home page -│ │ ├──OptionPage.ets // Page for selecting stocks -│ │ └──StockDetailsPage.ets // Stock details page -│ ├──utils -│ │ ├──BreakpointType.ets // Breakpoint class -│ │ └──Logger.ets // Logging utility -│ └──views -│ ├──BuyPopUp.ets // Dialog component for stock purchase -│ ├──CommonView.ets // Common component -│ ├──RegularWayPopUp.ets // Dialog component for regular transaction -│ ├──StockDealDetails.ets // Stock details component -│ ├──StockDetailsInfo.ets // Stock details information component -│ ├──StockDetailsView.ets // Stock details page component -│ ├──StockTable.ets // Stock table list component -│ └──TopTitleBar.ets // Top title bar of the stock details page -└──entry/src/main/resources // Application resources +├──commons +│ └──base/src/main/ets +│ └──utils +│ ├──BreakpointType.ets // Breakpoint type +│ ├──Logger.ets // Log type +│ └──WindowUtil.ets // Window Utility Class +├──features +│ ├──home/src/main/ets +│ │ ├──models +│ │ │ └──DataModel.ets // Stock data +│ │ ├──pages +│ │ │ ├──Home.ets // Home page +│ │ │ ├──OptionPage.ets // Page for selecting stocks +│ │ │ └──StockDetails.ets // Stock details page +│ │ └──views +│ │ ├──CommonView.ets // Common component +│ │ └──StockTable.ets // Stock table list component +│ └──home/src/main/resources // Application resources +│ ├──stockdetail/src/main/ets +│ │ ├──chartmodels +│ │ │ ├──BarChartView.ets // Bar chart component logic +│ │ │ ├──ChartAxisFormatter.ets // Line chart data formatting +│ │ │ └──LineChartModel.ets // Line chart component logic +│ │ ├──models +│ │ │ └──DataModel.ets // Stock data +│ │ ├──pages +│ │ │ └──StockDetailsPage.ets // Stock details page +│ │ └──views +│ │ ├──BuyPopUp.ets // Dialog component for stock purchase +│ │ ├──CommonView.ets // Common component +│ │ ├──MultiWindowEntryComponent.ets // Split-screen component +│ │ ├──RegularWayPopUp.ets // Dialog component for regular transaction +│ │ ├──StockDealDetails.ets // Stock details component +│ │ ├──StockDetailsInfo.ets // Stock details information component +│ │ ├──StockTable.ets // Stock table list component +│ │ └──TopTitleBar.ets // Top title bar of the stock details page +│ └──stockdetail/src/main/resources // Application resources +└──products + ├──phone/src/main/ets + │ ├──entryability + │ │ └──EntryAbility.ets // Program Entry Class + │ ├──entrybackupability + │ │ └──EntryBackupAbility.ets + │ ├──pages + │ │ └──Index.ets // Home page + │ ├──splitScreenAbility + │ │ └──SplitScreenAbility.ets // Split-screen entrance + │ └──splitScreenBackupAbility + │ └──SplitScreenBackupAbility.ets + └──phone/src/main/resources // Application resources ``` ## How to Implement -* Use the **UIAbilityContext.startAbility()** method to implement the in-application split-screen feature. -* Change **mode** of **navigation** based on the breakpoint or status to implement the transitions between single-column and triple-column layouts. +* By leveraging the multi-window interface provided by the MultiWindowEntryInAPP component within the application, an experience of multiple windows running concurrently within a single application is achieved. +* Based on different breakpoints or state changes, modify the mode attribute of the navigation to achieve the switching effect between single-column and three-column layouts. +* The column chart and line chart use the mpchart third-party library. ## Required Permissions @@ -99,6 +122,7 @@ N/A ## Constraints 1. This sample is only supported on Huawei phones and tablets running standard systems. -2. The HarmonyOS version must be HarmonyOS 5.0.5 Release or later. -3. The DevEco Studio version must be DevEco Studio 5.0.5 Release or later. -4. The HarmonyOS SDK version must be HarmonyOS 5.0.5 Release SDK or later. +2. The HarmonyOS version must be HarmonyOS 6.0.0 Release or later. +3. The DevEco Studio version must be DevEco Studio 6.0.0 Release or later. +4. The HarmonyOS SDK version must be HarmonyOS 6.0.0 Release SDK or later. +5. This sample enters the MultiWindowEntryInAPP component for use in multi-window mode (split-screen or full-screen). Currently, devices that support the MultiWindowEntryInAPP component for multi-window mode include: Mate X5, Mate X6, Mate XTs, MatePad Air 12-inch (2025), MatePad Pro 12.2-inch (2025), and MatePad Pro 13.2-inch (2025). diff --git a/README.md b/README.md index 8476459e1245ef0d36699a5f9858c37802787c5f..14d33f343f173acc81e2744c8fa631e8404596ec 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## 介绍 -本篇Sample基于自适应布局和响应式布局,实现一次开发,多端部署的股票交易应用。根据不同设备尺寸(如手机、折叠屏、平板),实现了相应的页面布局。该Sample支持在大折叠、三折叠和平板设备上分屏显示,便于对比股票详情。 +本篇Sample基于自适应布局和响应式布局,实现一次开发,多端部署的股票交易应用。根据不同设备尺寸(如手机、折叠屏、平板),实现了相应的页面布局。该Sample支持在双折叠、三折叠和平板设备上分屏显示,便于对比股票详情。 ## 效果预览 @@ -48,48 +48,70 @@ 1. 折叠屏(展开态)或平板:点击页面右上角的“分屏”图标,应用进入分屏模式; - 2. 平板:右侧“内容区”页面,点击页面左上角的“放大”图标,应用进入全屏。全屏下,点击页面左上角的“返回”图标,应用退出全屏; + 2. 平板:右侧“股票详情”页面,点击页面左上角的“放大”图标,股票详情页进入全屏。全屏下,点击页面左上角的“返回”图标,股票详情页退出全屏; 3. 点击页面下方的“去交易”按钮,页面弹出“买入股票弹窗”。当前弹框,点击“买入”按钮,弹出“确认买入股票弹窗”。 ## 工程目录 ``` -├──entry/src/main/ets // 代码区 -│ ├──chartmodels -│ │ ├──BarChartView.ets // 柱状图组件逻辑 -│ │ ├──ChartAxisFormatter.ets // 折线图数据格式化 -│ │ └──LineChartModel.ets // 折线图组件逻辑 -│ ├──entryability -│ │ └──EntryAbility.ets // 程序入口 -│ ├──entrybackupability -│ │ └──EntryBackupAbility.ets // 数据备份恢复类 -│ ├──models -│ │ └──DataModel.ets // 股票类数据 -│ ├──pages -│ │ ├──Index.ets // 应用首页 -│ │ ├──OptionPage.ets // 自选页 -│ │ └──StockDetailsPage.ets // 股票详情页 -│ ├──utils -│ │ ├──BreakpointType.ets // 断点类 -│ │ └──Logger.ets // 日志 -│ └──views -│ ├──BuyPopUp.ets // 买入弹窗组件 -│ ├──CommonView.ets // 公共组件 -│ ├──RegularWayPopUp.ets // 普通交易弹窗组件 -│ ├──StockDealDetails.ets // 股票详情组件 -│ ├──StockDetailsInfo.ets // 股票详情信息组件 -│ ├──StockDetailsView.ets // 股票详情页组件 -│ ├──StockTable.ets // 股票表格列表组件 -│ └──TopTitleBar.ets // 股票详情页顶部标题栏 -└──entry/src/main/resources // 应用资源目录 - +├──commons +│ └──base/src/main/ets +│ └──utils +│ ├──BreakpointType.ets // 断点类型 +│ ├──Logger.ets // 日志类 +│ └──WindowUtil.ets // 窗口工具类 +├──features +│ ├──home/src/main/ets +│ │ ├──models +│ │ │ └──DataModel.ets // 股票类数据 +│ │ ├──pages +│ │ │ ├──Home.ets // 应用首页内容 +│ │ │ ├──OptionPage.ets // 自选页 +│ │ │ └──StockDetails.ets // 股票详情页 +│ │ └──views +│ │ ├──CommonView.ets // 公共组件 +│ │ └──StockTable.ets // 股票表格列表组件 +│ └──home/src/main/resources // 应用静态资源目录 +│ ├──stockdetail/src/main/ets +│ │ ├──chartmodels +│ │ │ ├──BarChartView.ets // 柱状图组件逻辑 +│ │ │ ├──ChartAxisFormatter.ets // 折线图数据格式化 +│ │ │ └──LineChartModel.ets // 折线图组件逻辑 +│ │ ├──models +│ │ │ └──DataModel.ets // 股票类数据 +│ │ ├──pages +│ │ │ └──StockDetailsPage.ets // 股票详情页 +│ │ └──views +│ │ ├──BuyPopUp.ets // 买入弹窗组件 +│ │ ├──CommonView.ets // 公共组件 +│ │ ├──MultiWindowEntryComponent.ets // 分屏组件 +│ │ ├──RegularWayPopUp.ets // 普通交易弹窗组件 +│ │ ├──StockDealDetails.ets // 股票详情组件 +│ │ ├──StockDetailsInfo.ets // 股票详情信息组件 +│ │ ├──StockTable.ets // 股票表格列表组件 +│ │ └──TopTitleBar.ets // 股票详情页顶部标题栏 +│ └──stockdetail/src/main/resources // 应用静态资源目录 +└──products + ├──phone/src/main/ets + │ ├──entryability + │ │ └──EntryAbility.ets // 程序入口类 + │ ├──entrybackupability + │ │ └──EntryBackupAbility.ets + │ ├──pages + │ │ └──Index.ets // 首页 + │ ├──splitScreenAbility + │ │ └──SplitScreenAbility.ets // 分屏入口 + │ └──splitScreenBackupAbility + │ └──SplitScreenBackupAbility.ets + └──phone/src/main/resources // 应用静态资源目录 ``` ## 具体实现 -* 使用UIAbilityContext.startAbility()方法实现应用内分屏功能。 +* 通过应用内多窗组件MultiWindowEntryInAPP提供的单应用多窗口接口,实现一个应用多个窗口并行运行的体验。 * 根据不同断点或状态改变navigation的mode属性,实现单栏和三栏的切换效果。 +* 柱状图和折线图使用mpchart三方库。 ## 相关权限 @@ -107,4 +129,7 @@ 3. DevEco Studio版本:DevEco Studio 6.0.0 Release及以上。 -4. HarmonyOS SDK版本:HarmonyOS 6.0.0 Release SDK及以上。 \ No newline at end of file +4. HarmonyOS SDK版本:HarmonyOS 6.0.0 Release SDK及以上。 + +5. 该Sample进入分屏/全景多窗使用的MultiWindowEntryInAPP组件,目前支持分屏/全景多窗(MultiWindowEntryInAPP组件)设备有: Mate X5、Mate X6、Mate XTs、MatePad Air 12英寸(2025)、MatePad Pro 12.2 英寸(2025)、MatePad Pro 13.2 英寸(2025)。 + diff --git a/build-profile.json5 b/build-profile.json5 index c4e8cef12735e3a7929c1740117603c46528ebe4..d827cd55d279e380f330e74ae6fdd810b5bd03ae 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -7,13 +7,7 @@ "signingConfig": "default", "targetSdkVersion": "6.0.0(20)", "compatibleSdkVersion": "6.0.0(20)", - "runtimeOS": "HarmonyOS", - "buildOption": { - "strictMode": { - "caseSensitiveCheck": true, - "useNormalizedOHMUrl": true - } - } + "runtimeOS": "HarmonyOS" } ], "buildModeSet": [ @@ -27,8 +21,44 @@ }, "modules": [ { - "name": "entry", - "srcPath": "./entry", + "name": "phone", + "srcPath": "./products/phone", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "base", + "srcPath": "./commons/base", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "home", + "srcPath": "./features/home", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "stockdetail", + "srcPath": "./features/stockdetail", "targets": [ { "name": "default", diff --git a/commons/base/Index.ets b/commons/base/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..a003d070815bf357d0fb333124eb4f226dbb24ee --- /dev/null +++ b/commons/base/Index.ets @@ -0,0 +1 @@ +export { WindowUtil } from './src/main/ets/utils/WindowUtil'; diff --git a/commons/base/build-profile.json5 b/commons/base/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b23faedd59a8acfcb14f7fda7afcd08500bede8e --- /dev/null +++ b/commons/base/build-profile.json5 @@ -0,0 +1,9 @@ +{ + "apiType": "stageMode", + "buildOption": {}, + "targets": [ + { + "name": "default" + } + ] +} \ No newline at end of file diff --git a/commons/base/hvigorfile.ts b/commons/base/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b21942e5edcee4beed541e842b8d0d58eda4a85 --- /dev/null +++ b/commons/base/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/commons/base/oh-package.json5 b/commons/base/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c764a93a96ab677a53c95087b3858bd0524e4e76 --- /dev/null +++ b/commons/base/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "license": "Apache-2.0", + "devDependencies": {}, + "author": "", + "name": "base", + "description": "Please describe the basic information.", + "main": "Index.ets", + "version": "1.0.0", + "dynamicDependencies": {}, + "dependencies": {} +} diff --git a/entry/src/main/ets/utils/BreakpointType.ets b/commons/base/src/main/ets/utils/BreakpointType.ets similarity index 67% rename from entry/src/main/ets/utils/BreakpointType.ets rename to commons/base/src/main/ets/utils/BreakpointType.ets index 222bb67424cfb08e74cd56b57d259014dc4df992..16221e2e4545e8f848228b336afdd9c5416a50a5 100644 --- a/entry/src/main/ets/utils/BreakpointType.ets +++ b/commons/base/src/main/ets/utils/BreakpointType.ets @@ -14,24 +14,31 @@ */ export class BreakpointType { + xs: T; sm: T; md: T; lg: T; + xl: T; - constructor(sm: T, md: T, lg: T) { + constructor(xs: T, sm: T, md: T, lg: T, xl: T) { + this.xs = xs; this.sm = sm; this.md = md; this.lg = lg; + this.xl = xl; } getValue(currentWidthBreakpoint: number): T { - if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_MD) { + if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_XS) { + return this.xs; + }else if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM) { + return this.sm; + } else if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_MD) { return this.md; - } - if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG) { + } else if (currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG) { return this.lg; } else { - return this.sm; + return this.xl; } } } \ No newline at end of file diff --git a/entry/src/main/ets/utils/Logger.ets b/commons/base/src/main/ets/utils/Logger.ets similarity index 100% rename from entry/src/main/ets/utils/Logger.ets rename to commons/base/src/main/ets/utils/Logger.ets diff --git a/commons/base/src/main/ets/utils/WindowUtil.ets b/commons/base/src/main/ets/utils/WindowUtil.ets new file mode 100644 index 0000000000000000000000000000000000000000..df638f54335bd12782174c4ee02e3a8391024d9e --- /dev/null +++ b/commons/base/src/main/ets/utils/WindowUtil.ets @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BusinessError } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +@Observed +export class WindowUtil { + private windowStage?: window.WindowStage; + private mainWindowClass?: window.Window; + + static getInstance(): WindowUtil | undefined { + if (!AppStorage.get('windowUtil')) { + AppStorage.setOrCreate('windowUtil', new WindowUtil()); + } else { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `AppStorage does not have windowUtil.`); + } + return AppStorage.get('windowUtil'); + } + + setWindowStage(windowStage: window.WindowStage): void { + this.windowStage = windowStage; + this.windowStage.getMainWindow((err, windowClass: window.Window) => { + this.mainWindowClass = windowClass; + if (err.code) { + hilog.error(0x0000, 'WindowUtil', `Failed to obtain the main window. Code:${err.code}, message:${err.message}`, + JSON.stringify(err) ?? ''); + return; + } + }); + } + + setMainWindowOrientation(orientation: window.Orientation): void { + // Setting orientation. + this.mainWindowClass!.setPreferredOrientation(orientation) + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in setting the orientation.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', `Failed to set the orientation. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + + disableWindowSystemBar(): void { + // Set the status bar and navigation bar to be invisible in full-screen mode. + this.mainWindowClass!.setWindowSystemBarEnable([]) + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in setting the window system bar disable.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', + `Failed to set the window system bar disable. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + + enableWindowSystemBar(): void { + this.mainWindowClass!.setWindowSystemBarEnable(['status', 'navigation']) + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in setting the window system bar enable.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', `Failed to set the orientation. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + + setFullScreen(): void { + // Set full-screen display. + this.mainWindowClass!.setWindowLayoutFullScreen(true) + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in setting the window layout full screen.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', + `Failed to set the window layout full screen. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + + maximize(): void { + if (canIUse('SystemCapability.Window.SessionManager')) { + try { + if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FLOATING) { + this.mainWindowClass!.maximize() + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in maximizing the window.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', + `Failed to maximize the window. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + } catch (error) { + let err = error as BusinessError; + hilog.error(0x00, 'WindowUtil', `getWindowStatus failed, code : ${err.code}, message : ${err.message}`); + } + } + } + + recover(): void { + if (canIUse('SystemCapability.Window.SessionManager')) { + try { + if (this.mainWindowClass!.getWindowStatus() === window.WindowStatusType.FULL_SCREEN) { + this.mainWindowClass!.recover() + .then(() => { + hilog.info(0x0000, 'WindowUtil', '%{public}s', `Succeed in rovering the window.`); + }) + .catch((err: BusinessError) => { + hilog.error(0x0000, 'WindowUtil', + `Failed to rover the window. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + }); + } + } catch (error) { + let err = error as BusinessError; + hilog.error(0x00, 'WindowUtil', `getWindowStatus failed, code : ${err.code}, message : ${err.message}`); + } + } + } + + getMainWindow(): window.Window | undefined { + return this.mainWindowClass; + } + + offWindowSizeChange(): void { + try { + this.mainWindowClass!.off('windowSizeChange'); + } catch (err) { + hilog.error(0x0000, 'WindowUtil', `Failed to off window size change. Code: ${err.code}, message: ${err.message}`, + JSON.stringify(err) ?? ''); + } + } +} \ No newline at end of file diff --git a/commons/base/src/main/module.json5 b/commons/base/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5b88767e30950571337935f398f2dcbf4d1b822d --- /dev/null +++ b/commons/base/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "base", + "type": "har", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ] + } +} \ No newline at end of file diff --git a/features/home/.gitignore b/features/home/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/features/home/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/features/home/Index.ets b/features/home/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..5fb14cd55a244aad515f1fed6362f2694ae6115d --- /dev/null +++ b/features/home/Index.ets @@ -0,0 +1 @@ +export { Home } from './src/main/ets/pages/Home'; \ No newline at end of file diff --git a/features/home/build-profile.json5 b/features/home/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3167e54d1ff3a0aaa0cdcf4319789de8e3f3c350 --- /dev/null +++ b/features/home/build-profile.json5 @@ -0,0 +1,10 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} \ No newline at end of file diff --git a/features/home/hvigorfile.ts b/features/home/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6b07e311078a9000fbdc694df98cbcd9f7ef8f6 --- /dev/null +++ b/features/home/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/features/home/oh-package.json5 b/features/home/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..969f4ad3b974699f710c1a9c91d7f1153a874c11 --- /dev/null +++ b/features/home/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "name": "home", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "@ohos/base": "file:../../commons/base", + "@ohos/stockdetail": "file:../../features/stockdetail" + } +} + diff --git a/features/home/src/main/ets/models/DataModel.ets b/features/home/src/main/ets/models/DataModel.ets new file mode 100644 index 0000000000000000000000000000000000000000..c73c758b8d3af06c208d77b8a377ce0fed9d61bd --- /dev/null +++ b/features/home/src/main/ets/models/DataModel.ets @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class ShareIndex { + title: ResourceStr; + index: string; + priceLimit: string; + + constructor(title: ResourceStr, index: string, priceLimit: string) { + this.title = title; + this.index = index; + this.priceLimit = priceLimit; + } +} + +export class StockForm { + title: ResourceStr; // Stock Name + stockNumber: ResourceStr; // Stock Number + latestPrice: number; // Latest Price + highsAndLows: number; // HighLow + priceLimit: ResourceStr; // Price Limit + gross: ResourceStr; // Gross + impressions: ResourceStr; // Impressions + plate: ResourceStr // Stock sector + plateFontColor: ResourceColor; // Font color of the stock section + plateBackgroundColor: ResourceColor; // Background color of the stock section + volumeTransaction: ResourceStr; // volume of transaction + amplitude: ResourceStr; // Amplitude + changeHands: ResourceStr; // Change Hands + PEG: number; // P/E ratio (price-to-earnings ratio) + PB: number; // PB(price/book value ratio) + + constructor(title: ResourceStr, stockNumber: ResourceStr, latestPrice: number, highsAndLows: number, + priceLimit: ResourceStr, gross: ResourceStr, impressions: ResourceStr, plate: ResourceStr, + plateFontColor: ResourceColor, plateBackgroundColor: ResourceColor, volumeTransaction: ResourceStr, + amplitude: ResourceStr, changeHands: ResourceStr, PEG: number, PB: number) { + this.title = title; + this.stockNumber = stockNumber; + this.latestPrice = latestPrice; + this.highsAndLows = highsAndLows; + this.priceLimit = priceLimit; + this.gross = gross; + this.impressions = impressions; + this.plate = plate; + this.plateFontColor = plateFontColor; + this.plateBackgroundColor = plateBackgroundColor; + this.volumeTransaction = volumeTransaction; + this.amplitude = amplitude; + this.changeHands = changeHands; + this.PEG = PEG; + this.PB = PB; + } +} + +export class StockInForm { + title1: ResourceStr; + value1: ResourceStr; + color1: ResourceStr; + title2: ResourceStr; + value2: ResourceStr; + color2: ResourceStr; + title3: ResourceStr; + value3: ResourceStr; + color3: ResourceStr; + + constructor( + title1: ResourceStr, value1: ResourceStr, color1: ResourceStr, + title2: ResourceStr, value2: ResourceStr, color2: ResourceStr, + title3: ResourceStr, value3: ResourceStr, color3: ResourceStr + ) { + this.title1 = title1; + this.value1 = value1; + this.color1 = color1; + this.title2 = title2; + this.value2 = value2; + this.color2 = color2; + this.title3 = title3; + this.value3 = value3; + this.color3 = color3; + } +} + +export class transactionDetails { + title: ResourceStr; + price: string; + amount: number; + + constructor(title: ResourceStr, price: string, amount: number) { + this.title = title; + this.price = price; + this.amount = amount; + } +} + +export const SHARE_INDEX: ShareIndex[] = [ + new ShareIndex($r('app.string.certain_index'), '3088.10', '+19.8 +0.64%'), + new ShareIndex($r('app.string.deep_number'), '3088.10', '+19.8 -0.64%'), + new ShareIndex($r('app.string.science_technology'), '3088.10', '+19.8 +0.64%'), + new ShareIndex($r('app.string.certain_index'), '3088.10', '+19.8 -0.64%'), + new ShareIndex($r('app.string.deep_number'), '3088.10', '+19.8 +0.64%') +]; + +export const STOCK_FORM: StockForm[] = [ + new StockForm($r('app.string.somebody_technology'), '60**39', 904, +0.04, '+0.53%', '310511', '1232', + $r('app.string.securities_margin_trading'), '#9801FF', '#F4E3FD', '12.5', '8.88%', '18.81%', 123, 1.5), + new StockForm($r('app.string.certain_estate_company'), '60**19', 182104, +3.04, '+0.19%', '30176', '550', + $r('app.string.securities_margin_trading'), '#9801FF', '#F4E3FD', '15.5', '8.98%', '15.81%', 112, 1.1), + new StockForm($r('app.string.certain_pharmaceutical_company'), '30**89', 1520, +0.16, '+1.04%', '19593', '3461', + $r('app.string.growth_enterprise_market'), '#FF5501', '#FFEEE5', '13.5', '6.58%', '19.81%', 116, 1.9), + new StockForm($r('app.string.somebody_technology'), '60**99', 2001, +3.04, '+0.19%', '7071', '4890', + $r('app.string.securities_margin_trading'), '#9801FF', '#F4E3FD', '10.5', '8.86%', '13.81%', 105, 1.5), + new StockForm($r('app.string.certain_estate_company'), '30**59', 2432, +0.16, '+1.04%', '6953', '1321', + $r('app.string.growth_enterprise_market'), '#FF5501', '#FFEEE5', '19.9', '6.88%', '12.81%', 108, 1.2) +]; + +export const STOCK_INFORM_LIST: StockInForm[] = [ + new StockInForm($r('app.string.now_begins'), '19.86', '#FA4337', $r('app.string.yesterday_close'), '19.84', '#000000', + $r('app.string.turnover_rate'), '0.39%', '#000000'), + new StockInForm($r('app.string.tallest'), '19.86', '#FA4337', $r('app.string.lowest'), '19.84', '#1DB775', + $r('app.string.PEG'), '95.32', '#000000'), + new StockInForm($r('app.string.turnover'), $r('app.string.text_hands'), '#000000', + $r('app.string.volume_transaction'), $r('app.string.turnover_value'), '#000000', $r('app.string.total_value'), + $r('app.string.text_billion'), '#000000'), + new StockInForm($r('app.string.now_begins'), '19.86', '#FA4337', $r('app.string.yesterday_close'), '19.84', '#000000', + $r('app.string.turnover_rate'), '0.39%', '#000000') +]; + +export const CYCLE_TITLE: ResourceStr[] = [ + $r('app.string.time_share'), $r('app.string.five_days'), $r('app.string.daily_k'), $r('app.string.week_k'), + $r('app.string.month_k'), $r('app.string.season_k'), $r('app.string.half_year_k'), $r('app.string.year_k') +]; + +export const OTHER_TITLE: ResourceStr[] = [ + $r('app.string.discussion'), $r('app.string.must_read'), $r('app.string.research_report'), + $r('app.string.capital'), $r('app.string.datum'), $r('app.string.announcements'), + $r('app.string.finance'), $r('app.string.information'), $r('app.string.related_fund') +]; + +export const SELL_SHARES: transactionDetails[] = [ + new transactionDetails($r('app.string.sell'), '20.10', 69), + new transactionDetails($r('app.string.sell'), '20.09', 12), + new transactionDetails($r('app.string.sell'), '20.08', 66), + new transactionDetails($r('app.string.sell'), '20.07', 55), + new transactionDetails($r('app.string.sell'), '20.06', 33) +]; + +export const BUY_SELL_SHARES: transactionDetails[] = [ + new transactionDetails($r('app.string.text_buy'), '20.05', 11), + new transactionDetails($r('app.string.text_buy'), '20.04', 22), + new transactionDetails($r('app.string.text_buy'), '20.03', 33), + new transactionDetails($r('app.string.text_buy'), '20.02', 55), + new transactionDetails($r('app.string.text_buy'), '20.01', 66) +]; + +export const SUBMISSION_TIME: transactionDetails[] = [ + new transactionDetails('10:02', '20.07', 11), + new transactionDetails('10:02', '20.07', 22), + new transactionDetails('10:02', '20.07', 33), + new transactionDetails('10:02', '20.08', 55), + new transactionDetails('10:02', '20.08', 66), + + new transactionDetails('10:01', '20.07', 33), + new transactionDetails('10:01', '20.07', 22), + new transactionDetails('10:01', '20.07', 66), + new transactionDetails('10:01', '20.07', 99), + new transactionDetails('10:01', '20.07', 77), + + new transactionDetails('10:00', '20.06', 33), + new transactionDetails('10:00', '20.06', 22), + new transactionDetails('10:00', '20.06', 66), + new transactionDetails('10:00', '20.05', 99), + new transactionDetails('10:00', '20.05', 77) +]; + +export const STOCK_TITLE: Resource[] = [ + $r('app.string.stock_name'), $r('app.string.latest_price'), $r('app.string.highs_and_lows'), + $r('app.string.price_limit'), $r('app.string.gross'), $r('app.string.impressions'), + $r('app.string.volume_transaction'), $r('app.string.amplitude'), $r('app.string.change_hands'), + $r('app.string.PEG'), $r('app.string.PB') +]; \ No newline at end of file diff --git a/entry/src/main/ets/pages/Index.ets b/features/home/src/main/ets/pages/Home.ets similarity index 94% rename from entry/src/main/ets/pages/Index.ets rename to features/home/src/main/ets/pages/Home.ets index dfa3ec729f2da48c4b8fcb4484ecbc5a40287a3f..157eb5043632e87613e824a64280933a2033b351 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/features/home/src/main/ets/pages/Home.ets @@ -13,13 +13,12 @@ * limitations under the License. */ -import { BreakpointType } from '../utils/BreakpointType'; -import { StockDetailsPage } from './StockDetailsPage'; +import { BreakpointType } from '@ohos/base/src/main/ets/utils/BreakpointType'; import { OptionPage } from './OptionPage'; +import { StockDetails } from './StockDetails'; -@Entry @Component -struct Index { +export struct Home { @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; @StorageLink('currentHeightBreakpoint') currentHeightBreakpoint: number = 1; @StorageLink('isSplitScreen') isSplitScreen: boolean = false; @@ -32,7 +31,7 @@ struct Index { @Builder pageMap(pageName: string): void { if (pageName === 'StockDetailsPage') { - StockDetailsPage(); + StockDetails(); } } @@ -101,7 +100,8 @@ struct Index { Column() { // [Start homepage_tabs] Tabs({ - barPosition: new BreakpointType(BarPosition.End, BarPosition.End, BarPosition.Start) + barPosition: new BreakpointType(BarPosition.End, BarPosition.End, BarPosition.End, BarPosition.Start, + BarPosition.Start) .getValue(this.currentWidthBreakpoint), index: 2 }) { @@ -161,7 +161,8 @@ struct Index { } .navDestination(this.pageMap) .navBarWidthRange([474, 474]) - .mode(new BreakpointType(NavigationMode.Stack, NavigationMode.Stack, this.tabletMode) + .mode(new BreakpointType(NavigationMode.Stack, NavigationMode.Stack, NavigationMode.Stack, this.tabletMode, + this.tabletMode) .getValue(this.currentWidthBreakpoint)) .hideTitleBar(true) .hideToolBar(true) diff --git a/entry/src/main/ets/pages/OptionPage.ets b/features/home/src/main/ets/pages/OptionPage.ets similarity index 82% rename from entry/src/main/ets/pages/OptionPage.ets rename to features/home/src/main/ets/pages/OptionPage.ets index 67e7e170d9f4d9d7d66b4c6a1f810f185ee66747..91137dcc461464b29a32d630ce907b920e99751f 100644 --- a/entry/src/main/ets/pages/OptionPage.ets +++ b/features/home/src/main/ets/pages/OptionPage.ets @@ -13,8 +13,8 @@ * limitations under the License. */ +import { BreakpointType } from '@ohos/base/src/main/ets/utils/BreakpointType'; import { ShareIndex, SHARE_INDEX } from '../models/DataModel'; -import { BreakpointType } from '../utils/BreakpointType'; import { StockTable } from '../views/StockTable'; @Component @@ -44,7 +44,7 @@ export struct OptionPage { } .height(32) } - .width(new BreakpointType(78, 101, 96).getValue(this.currentWidthBreakpoint)) + .width(new BreakpointType(78, 78, 101, 96, 96).getValue(this.currentWidthBreakpoint)) .height(73) .borderRadius(8) .justifyContent(FlexAlign.SpaceBetween) @@ -66,15 +66,15 @@ export struct OptionPage { .width('100%') .height(56) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) // [Start stock_list_area] // List of stock indices Row() { List({ - space: new BreakpointType(13, 14, 16).getValue(this.currentWidthBreakpoint), + space: new BreakpointType(13, 13, 14, 16, 16).getValue(this.currentWidthBreakpoint), initialIndex: 0 }) { ForEach(SHARE_INDEX, (item: ShareIndex, index: number) => { @@ -82,7 +82,7 @@ export struct OptionPage { this.ShareIndexBuilder(item, index) } .margin({ - left: index === 0 ? new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) : 0 + left: index === 0 ? new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) : 0 }) }, (item: ShareIndex, index: number) => (item.priceLimit + index).toString()) } @@ -127,11 +127,11 @@ export struct OptionPage { .fontSize(20) .margin({ bottom: 40, - left: new BreakpointType(4, 12, 18).getValue(this.currentWidthBreakpoint) + left: new BreakpointType(4, 4, 12, 18, 18).getValue(this.currentWidthBreakpoint) }) // [EndExclude stock_list_area] } - .width(new BreakpointType(78, 101, 96).getValue(this.currentWidthBreakpoint)) + .width(new BreakpointType(78, 78, 101, 96, 96).getValue(this.currentWidthBreakpoint)) // [StartExclude stock_list_area] .height(73) .justifyContent(FlexAlign.Center) @@ -143,7 +143,7 @@ export struct OptionPage { }) // [EndExclude stock_list_area] .margin({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) } // [End stock_list_area] @@ -197,17 +197,16 @@ export struct OptionPage { .height(48) .alignItems(VerticalAlign.Center) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) // [End stock_toolbar_area] + } + Column() { // Stock table list StockTable() - } - - // Add custom buttons - Row() { + // Add custom buttons Row() { Text($r('app.string.add_custom_options')) .fontSize(16) @@ -220,17 +219,19 @@ export struct OptionPage { .borderRadius(20) .width(240) .height(40) + .margin({ + top: 24 + }) } - .width('100%') - .justifyContent(FlexAlign.Center) .margin({ - top: 24 + bottom: 172 }) } .width('100%') .height('100%') .padding({ - top: AppStorage.get('statusBarHeight') + top: this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? 0 : AppStorage.get('statusBarHeight') }) } } \ No newline at end of file diff --git a/features/home/src/main/ets/pages/StockDetails.ets b/features/home/src/main/ets/pages/StockDetails.ets new file mode 100644 index 0000000000000000000000000000000000000000..74f1019323f5e0e09d7a9a72169fa1e05b92b874 --- /dev/null +++ b/features/home/src/main/ets/pages/StockDetails.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { StockDetailsPage } from '@ohos/stockdetail'; + +@Builder +export function StockDetails() { + StockDetailsPage() +} \ No newline at end of file diff --git a/entry/src/main/ets/views/CommonView.ets b/features/home/src/main/ets/views/CommonView.ets similarity index 55% rename from entry/src/main/ets/views/CommonView.ets rename to features/home/src/main/ets/views/CommonView.ets index 0bb62ac3d2f196747052b560ad9973de21cbf315..5862f907f02f36d2f6dbcd9935abf281cd167001 100644 --- a/entry/src/main/ets/views/CommonView.ets +++ b/features/home/src/main/ets/views/CommonView.ets @@ -14,147 +14,25 @@ */ import { OTHER_TITLE, StockInForm } from '../models/DataModel'; -import { BreakpointType } from '../utils/BreakpointType'; - -@Component -export struct WordBackgroundComm { - public text: ResourceStr = ''; - public textFontColor: ResourceColor = ''; - public textBackgroundColor: ResourceColor = ''; - - build() { - Row() { - Text(this.text) - .fontSize(10) - .fontColor(this.textFontColor) - } - .width(12) - .height(12) - .borderRadius(2) - .alignItems(VerticalAlign.Center) - .justifyContent(FlexAlign.Center) - .backgroundColor(this.textBackgroundColor) - .margin({ - right: 4 - }) - } -} - -@Component -export struct UniversalIcon { - public icon?: Resource; - public iconBackgroundColor: ResourceColor = ''; - public fontSize?: ResourceColor = $r('sys.float.Title_L'); - - build() { - Button({ type: ButtonType.Circle }) { - SymbolGlyph(this.icon) - .fontColor([$r('sys.color.icon_primary')]) - .fontSize(this.fontSize) - } - .height(46) - .aspectRatio(1) - .backgroundColor(this.iconBackgroundColor) - } -} - -@Component -export struct UniversalImage { - public icon?: Resource; - public iconBackgroundColor: ResourceColor = ''; - - build() { - Button({ type: ButtonType.Circle }) { - Image(this.icon) - .width($r('sys.float.Title_M')) - .height($r('sys.float.Title_M')) - } - .height(40) - .aspectRatio(1) - .backgroundColor(this.iconBackgroundColor) - } -} - -@Component -export struct StockDetails { - public title: ResourceStr = ''; - public price: string = ''; - public amount: number = 0; - public index: number = 0; - public isShowNumber: boolean = true; - - build() { - Row() { - Text(this.title) { - Span(this.title) - if (this.isShowNumber) { - Span(this.index.toString()) - } - } - .textType() - .fontColor('#666666') - - Text(this.price) - .textType() - .fontColor(this.index % 2 === 0 ? '#FA4337' : '#1DB775') - Text(this.amount.toString()) - .textType() - .fontColor('#666666') - .alignSelf(ItemAlign.End) - } - .width('100%') - .justifyContent(FlexAlign.SpaceBetween) - } -} - -@Component -export struct TitleIcon { - public icon?: Resource; - public title?: Resource; - - build() { - Column() { - SymbolGlyph(this.icon) - .fontColor([$r('sys.color.icon_primary')]) - .fontSize(24) - Text(this.title) - .fontSize(10) - .lineHeight(13) - .fontColor('#999999') - .margin({ - top: 4 - }) - } - .width(40) - .height(42) - .justifyContent(FlexAlign.Center) - .alignItems(HorizontalAlign.Center) - } -} - -@Component -export struct TitleImage { - public icon?: Resource; - public title?: Resource; - - build() { - Column() { - Image(this.icon) - .width(24) - .height(24) - Text(this.title) - .fontSize(10) - .lineHeight(13) - .fontColor('#999999') - .margin({ - top: 4 - }) - } - .width(40) - .height(42) - .justifyContent(FlexAlign.Center) - .alignItems(HorizontalAlign.Center) +import { BreakpointType } from '@ohos/base/src/main/ets/utils/BreakpointType'; + +@Builder +export function WordBackgroundComm(text: ResourceStr, textFontColor?: ResourceColor, + textBackgroundColor?: ResourceColor) { + Row() { + Text(text) + .fontSize(10) + .fontColor(textFontColor) } + .width(12) + .height(12) + .borderRadius(2) + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.Center) + .backgroundColor(textBackgroundColor) + .margin({ + right: 4 + }) } @Component @@ -186,8 +64,8 @@ export struct StockInFormList { .textStocksTitleValue() } .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) Divider() @@ -222,7 +100,7 @@ export struct CommSlide { build() { // [Start tab_sliding_area] List({ - space: new BreakpointType(46, 90, 150).getValue(this.currentWidthBreakpoint) + space: new BreakpointType(46, 46, 90, 150, 150).getValue(this.currentWidthBreakpoint) }) { ForEach(this.commSlideData, (item: string, index: number) => { ListItem() { @@ -241,8 +119,8 @@ export struct CommSlide { .margin({ top: 9, right: this.commSlideData.length === index + 1 ? - new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) : 0, - left: index === 0 ? new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) : 0, + new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) : 0, + left: index === 0 ? new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) : 0, }) .border({ width: { @@ -266,13 +144,6 @@ export struct CommSlide { } } -@Extend(Text) -function textType() { - .fontWeight(FontWeight.Regular) - .fontSize(10) - .lineHeight(14) -} - @Extend(Text) function textStocksTitle() { .fontSize(11) diff --git a/entry/src/main/ets/views/StockTable.ets b/features/home/src/main/ets/views/StockTable.ets similarity index 89% rename from entry/src/main/ets/views/StockTable.ets rename to features/home/src/main/ets/views/StockTable.ets index 6603b8665b26ce2c1f9e37172e5d144ba74102e6..d71a2d41df0bf742bd5c9c9bf853730195e95607 100644 --- a/entry/src/main/ets/views/StockTable.ets +++ b/features/home/src/main/ets/views/StockTable.ets @@ -13,8 +13,8 @@ * limitations under the License. */ +import { BreakpointType } from '@ohos/base/src/main/ets/utils/BreakpointType'; import { StockForm, STOCK_FORM, STOCK_TITLE } from '../models/DataModel'; -import { BreakpointType } from '../utils/BreakpointType'; import { WordBackgroundComm } from './CommonView'; @Component @@ -36,10 +36,9 @@ export struct StockTable { .width(index === 1 || index === 2 || index === 3 ? 90 : 100) .padding({ right: index === STOCK_TITLE.length - 1 ? - (new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint)) : 0, - left: index === 0 ? (new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint)) : 0 + (new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint)) : 0, + left: index === 0 ? (new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint)) : 0 }) - }, (item: Resource, index: number) => item.toString() + index) } .height(36) @@ -66,18 +65,13 @@ export struct StockTable { .height(21) .width(64) .maxLines(1) - Row() { Text(item.stockNumber) .fontSize(12) .height(16) .fontColor($r('sys.color.font_tertiary')) .textAlign(TextAlign.Start) - WordBackgroundComm({ - text: item.plate, - textFontColor: item.plateFontColor, - textBackgroundColor: item.plateBackgroundColor - }) + WordBackgroundComm(item.plate, item.plateFontColor, item.plateBackgroundColor) } .width(64) .justifyContent(FlexAlign.SpaceBetween) @@ -87,7 +81,7 @@ export struct StockTable { // [StartExclude stock_list_area] .width(100) .padding({ - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) Text((item.latestPrice / 100).toString()) @@ -160,12 +154,15 @@ export struct StockTable { .width(100) .fontWeight(FontWeight.Medium) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) // [EndExclude stock_list_area] } } .height(56) + .onClick(() => { + this.pageInfos.replacePathByName('StockDetailsPage', item, true); + }) }, (item: StockForm, index: number) => (item.latestPrice + index).toString()) // [StartExclude stock_list_area] ListItem() { @@ -177,9 +174,6 @@ export struct StockTable { } .scrollBar(BarState.Off) .sticky(StickyStyle.Header) - .onClick(() => { - this.pageInfos.replacePathByName('StockDetailsPage', null, true); - }) } .scrollable(ScrollDirection.Horizontal) // Rolling direction: vertical .scrollBar(BarState.Off) // Permanent display of the scroll bar diff --git a/features/home/src/main/module.json5 b/features/home/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a40a436c346c4b3523266ab801e76f4d38bcec0 --- /dev/null +++ b/features/home/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "home", + "type": "har", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ] + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color.json b/features/home/src/main/resources/base/element/color.json similarity index 100% rename from entry/src/main/resources/base/element/color.json rename to features/home/src/main/resources/base/element/color.json diff --git a/entry/src/main/resources/base/element/float.json b/features/home/src/main/resources/base/element/float.json similarity index 100% rename from entry/src/main/resources/base/element/float.json rename to features/home/src/main/resources/base/element/float.json diff --git a/entry/src/main/resources/base/element/string.json b/features/home/src/main/resources/base/element/string.json similarity index 98% rename from entry/src/main/resources/base/element/string.json rename to features/home/src/main/resources/base/element/string.json index a0796e1d1845d31c02977a58de45cf31652fda05..7ece632447cf36ff21e7e1bd6c1500d3fa3308e4 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/features/home/src/main/resources/base/element/string.json @@ -5,11 +5,11 @@ "value": "module description" }, { - "name": "EntryAbility_desc", + "name": "HomeAbility_desc", "value": "description" }, { - "name": "EntryAbility_label", + "name": "HomeAbility_label", "value": "MultiStockCategoryApp" }, { diff --git a/entry/src/main/resources/base/media/background.png b/features/home/src/main/resources/base/media/background.png similarity index 100% rename from entry/src/main/resources/base/media/background.png rename to features/home/src/main/resources/base/media/background.png diff --git a/entry/src/main/resources/base/media/doc_plaintext_fill.svg b/features/home/src/main/resources/base/media/doc_plaintext_fill.svg similarity index 100% rename from entry/src/main/resources/base/media/doc_plaintext_fill.svg rename to features/home/src/main/resources/base/media/doc_plaintext_fill.svg diff --git a/entry/src/main/resources/base/media/doc_text_fill.svg b/features/home/src/main/resources/base/media/doc_text_fill.svg similarity index 100% rename from entry/src/main/resources/base/media/doc_text_fill.svg rename to features/home/src/main/resources/base/media/doc_text_fill.svg diff --git a/entry/src/main/resources/base/media/foreground.png b/features/home/src/main/resources/base/media/foreground.png similarity index 100% rename from entry/src/main/resources/base/media/foreground.png rename to features/home/src/main/resources/base/media/foreground.png diff --git a/entry/src/main/resources/base/media/house_fill.svg b/features/home/src/main/resources/base/media/house_fill.svg similarity index 100% rename from entry/src/main/resources/base/media/house_fill.svg rename to features/home/src/main/resources/base/media/house_fill.svg diff --git a/entry/src/main/resources/base/media/layered_image.json b/features/home/src/main/resources/base/media/layered_image.json similarity index 100% rename from entry/src/main/resources/base/media/layered_image.json rename to features/home/src/main/resources/base/media/layered_image.json diff --git a/entry/src/main/resources/base/media/rectangle_split_2x1.png b/features/home/src/main/resources/base/media/rectangle_split_2x1.png similarity index 100% rename from entry/src/main/resources/base/media/rectangle_split_2x1.png rename to features/home/src/main/resources/base/media/rectangle_split_2x1.png diff --git a/entry/src/main/resources/base/media/split_screen.png b/features/home/src/main/resources/base/media/split_screen.png similarity index 100% rename from entry/src/main/resources/base/media/split_screen.png rename to features/home/src/main/resources/base/media/split_screen.png diff --git a/entry/src/main/resources/base/media/square_and_pencil_fill.svg b/features/home/src/main/resources/base/media/square_and_pencil_fill.svg similarity index 100% rename from entry/src/main/resources/base/media/square_and_pencil_fill.svg rename to features/home/src/main/resources/base/media/square_and_pencil_fill.svg diff --git a/entry/src/main/resources/base/media/startIcon.png b/features/home/src/main/resources/base/media/startIcon.png similarity index 100% rename from entry/src/main/resources/base/media/startIcon.png rename to features/home/src/main/resources/base/media/startIcon.png diff --git a/entry/src/main/resources/base/media/stocks_pk.png b/features/home/src/main/resources/base/media/stocks_pk.png similarity index 100% rename from entry/src/main/resources/base/media/stocks_pk.png rename to features/home/src/main/resources/base/media/stocks_pk.png diff --git a/entry/src/main/resources/base/profile/backup_config.json b/features/home/src/main/resources/base/profile/backup_config.json similarity index 100% rename from entry/src/main/resources/base/profile/backup_config.json rename to features/home/src/main/resources/base/profile/backup_config.json diff --git a/features/home/src/main/resources/base/profile/main_pages.json b/features/home/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..4ba14aff5d3509451ee9a5587c45cb934a3c76af --- /dev/null +++ b/features/home/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Home" + ] +} diff --git a/entry/src/main/resources/dark/element/color.json b/features/home/src/main/resources/dark/element/color.json similarity index 100% rename from entry/src/main/resources/dark/element/color.json rename to features/home/src/main/resources/dark/element/color.json diff --git a/entry/src/main/resources/en_US/element/string.json b/features/home/src/main/resources/en_US/element/string.json similarity index 98% rename from entry/src/main/resources/en_US/element/string.json rename to features/home/src/main/resources/en_US/element/string.json index a0796e1d1845d31c02977a58de45cf31652fda05..7ece632447cf36ff21e7e1bd6c1500d3fa3308e4 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/features/home/src/main/resources/en_US/element/string.json @@ -5,11 +5,11 @@ "value": "module description" }, { - "name": "EntryAbility_desc", + "name": "HomeAbility_desc", "value": "description" }, { - "name": "EntryAbility_label", + "name": "HomeAbility_label", "value": "MultiStockCategoryApp" }, { diff --git a/entry/src/main/resources/zh_CN/element/string.json b/features/home/src/main/resources/zh_CN/element/string.json similarity index 98% rename from entry/src/main/resources/zh_CN/element/string.json rename to features/home/src/main/resources/zh_CN/element/string.json index 2d2b65c6e54122201e199c8fa01f00ab69d7f887..9de301621324e0b650facd6824739d3cae4ab18e 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/features/home/src/main/resources/zh_CN/element/string.json @@ -5,11 +5,11 @@ "value": "module description" }, { - "name": "EntryAbility_desc", + "name": "HomeAbility_desc", "value": "description" }, { - "name": "EntryAbility_label", + "name": "HomeAbility_label", "value": "一多股票类应用" }, { diff --git a/features/stockdetail/Index.ets b/features/stockdetail/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..bd48e93431c431dec9b928d4aa830cb9116cfd42 --- /dev/null +++ b/features/stockdetail/Index.ets @@ -0,0 +1 @@ +export { StockDetailsPage } from './src/main/ets/pages/StockDetailsPage'; \ No newline at end of file diff --git a/features/stockdetail/build-profile.json5 b/features/stockdetail/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3167e54d1ff3a0aaa0cdcf4319789de8e3f3c350 --- /dev/null +++ b/features/stockdetail/build-profile.json5 @@ -0,0 +1,10 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} \ No newline at end of file diff --git a/features/stockdetail/hvigorfile.ts b/features/stockdetail/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6b07e311078a9000fbdc694df98cbcd9f7ef8f6 --- /dev/null +++ b/features/stockdetail/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/entry/oh-package.json5 b/features/stockdetail/oh-package.json5 similarity index 59% rename from entry/oh-package.json5 rename to features/stockdetail/oh-package.json5 index 248c3b7541a589682a250f86a6d3ecf7414d2d6a..fe7fa929817df8a9955d8c048d92fd3da7693f4d 100644 --- a/entry/oh-package.json5 +++ b/features/stockdetail/oh-package.json5 @@ -1,10 +1,11 @@ { - "name": "entry", + "name": "stockdetail", "version": "1.0.0", "description": "Please describe the basic information.", "main": "", "author": "", "license": "", - "dependencies": {} -} - + "dependencies": { + "base": "file:../../commons/base" + } +} \ No newline at end of file diff --git a/entry/src/main/ets/chartmodels/BarChartView.ets b/features/stockdetail/src/main/ets/chartmodels/BarChartView.ets similarity index 99% rename from entry/src/main/ets/chartmodels/BarChartView.ets rename to features/stockdetail/src/main/ets/chartmodels/BarChartView.ets index 29d0d005c6cf829c6b88363e1c6a8a10b2316da1..8e43a097003ad294e2d568ce02e130930d9779cc 100644 --- a/entry/src/main/ets/chartmodels/BarChartView.ets +++ b/features/stockdetail/src/main/ets/chartmodels/BarChartView.ets @@ -33,7 +33,7 @@ import { XAxis, YAxis } from '@ohos/mpchart'; -import Logger from '../utils/Logger'; +import Logger from 'base/src/main/ets/utils/Logger'; @Component export struct BarChartView { diff --git a/entry/src/main/ets/chartmodels/ChartAxisFormatter.ets b/features/stockdetail/src/main/ets/chartmodels/ChartAxisFormatter.ets similarity index 97% rename from entry/src/main/ets/chartmodels/ChartAxisFormatter.ets rename to features/stockdetail/src/main/ets/chartmodels/ChartAxisFormatter.ets index 3d302a5f9662f28098a991bd3c784d01323af992..e1d58245318bdd71fb98dc5d65e470326e1a3ad3 100644 --- a/entry/src/main/ets/chartmodels/ChartAxisFormatter.ets +++ b/features/stockdetail/src/main/ets/chartmodels/ChartAxisFormatter.ets @@ -17,7 +17,6 @@ import { HashMap } from '@kit.ArkTS'; import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { IAxisValueFormatter } from '@ohos/mpchart'; -import Logger from '../utils/Logger'; export class ChartAxisFormatter implements IAxisValueFormatter { xAxis: HashMap = new HashMap(); diff --git a/entry/src/main/ets/chartmodels/LineChartModel.ets b/features/stockdetail/src/main/ets/chartmodels/LineChartModel.ets similarity index 98% rename from entry/src/main/ets/chartmodels/LineChartModel.ets rename to features/stockdetail/src/main/ets/chartmodels/LineChartModel.ets index a26509e1a36c893cf4082083e6e060c13325ab24..4559f3be77c32bb70c0689ce26c10cb2d25801a5 100644 --- a/entry/src/main/ets/chartmodels/LineChartModel.ets +++ b/features/stockdetail/src/main/ets/chartmodels/LineChartModel.ets @@ -33,7 +33,7 @@ import { ChartAxisFormatter } from './ChartAxisFormatter'; import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; -class LinesChartModel { +export class LinesChartModel { xAxis: XAxis | null = null; topAxis: XAxis | null = null; mWidth: number = 312; @@ -194,6 +194,4 @@ class LinesChartModel { this.lineChartModel.setScaleEnabled(false); // Disable zooming. return this.lineChartModel; } -} - -export default new LinesChartModel(); \ No newline at end of file +} \ No newline at end of file diff --git a/entry/src/main/ets/models/DataModel.ets b/features/stockdetail/src/main/ets/models/DataModel.ets similarity index 99% rename from entry/src/main/ets/models/DataModel.ets rename to features/stockdetail/src/main/ets/models/DataModel.ets index ec259fd980adf23987d6a31356badce095d2e12f..9a44b1ad2c37a5052e566c9ebe33486b3df89a73 100644 --- a/entry/src/main/ets/models/DataModel.ets +++ b/features/stockdetail/src/main/ets/models/DataModel.ets @@ -121,7 +121,7 @@ export const STOCK_FORM: StockForm[] = [ $r('app.string.growth_enterprise_market'), '#FF5501', '#FFEEE5', '13.5', '6.58%', '19.81%', 116, 1.9), new StockForm($r('app.string.somebody_technology'), '60**99', 2001, +3.04, '+0.19%', '7071', '4890', $r('app.string.securities_margin_trading'), '#9801FF', '#F4E3FD', '10.5', '8.86%', '13.81%', 105, 1.5), - new StockForm($r('app.string.certain_estate_company'), '30**59', 2432, -0.16, '-1.04%', '6953', '1321', + new StockForm($r('app.string.certain_estate_company'), '30**59', 2432, +0.16, '+1.04%', '6953', '1321', $r('app.string.growth_enterprise_market'), '#FF5501', '#FFEEE5', '19.9', '6.88%', '12.81%', 108, 1.2) ]; diff --git a/entry/src/main/ets/views/StockDetailsView.ets b/features/stockdetail/src/main/ets/pages/StockDetailsPage.ets similarity index 66% rename from entry/src/main/ets/views/StockDetailsView.ets rename to features/stockdetail/src/main/ets/pages/StockDetailsPage.ets index acd104974403dd5073f62a3e43c2368ce728c77b..6d5d1c3fbc14dca88ec1105df97661a0719b0028 100644 --- a/entry/src/main/ets/views/StockDetailsView.ets +++ b/features/stockdetail/src/main/ets/pages/StockDetailsPage.ets @@ -16,20 +16,21 @@ import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; -import { LineChart, LineChartModel } from '@ohos/mpchart'; -import { CYCLE_TITLE, OTHER_TITLE } from '../models/DataModel'; +import { LineChart } from '@ohos/mpchart'; +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; +import { StockDetailsInfo } from '../views/StockDetailsInfo'; +import { StockDealDetails } from '../views/StockDealDetails'; +import { CommSlide, TitleIcon } from '../views/CommonView'; +import { RegularWayPopUp } from '../views/RegularWayPopUp'; +import { TopTitleBar } from '../views/TopTitleBar'; +import { BuyPopUp } from '../views/BuyPopUp'; +import { CYCLE_TITLE, OTHER_TITLE, StockForm, STOCK_FORM } from '../models/DataModel'; +import { LinesChartModel } from '../chartmodels/LineChartModel'; import { BarChartView } from '../chartmodels/BarChartView'; -import { BreakpointType } from '../utils/BreakpointType'; -import { StockDetailsInfo } from './StockDetailsInfo'; -import { StockDealDetails } from './StockDealDetails'; -import { CommSlide, TitleIcon } from './CommonView'; -import { RegularWayPopUp } from './RegularWayPopUp'; -import { TopTitleBar } from './TopTitleBar'; -import { BuyPopUp } from './BuyPopUp'; -import ChartViewModel from '../chartmodels/LineChartModel'; @Component -export struct StockDetailsView { +export struct StockDetailsPage { + @StorageLink('curWindowSizeWidth') curWindowSizeWidth: number = 1; @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; @StorageLink('currentHeightBreakpoint') currentHeightBreakpoint: number = 1; @StorageLink('lastWidthBreakpoint') lastWidthBreakpoint: number = 1; @@ -37,14 +38,15 @@ export struct StockDetailsView { @StorageLink('isSplitScreen') isSplitScreen: boolean = false; @Consume('pageInfos') pageInfos: NavPathStack; @Consume('tabletMode') tabletMode: NavigationMode; - @State lineChartModel: LineChartModel = ChartViewModel.getLineChartModel(); + @State ChartViewModel: LinesChartModel = new LinesChartModel(); @State cycleTabIndexSelected: number = 0; @State currentIndex: number = 0; @State selectedIndex: number = 0; - private scroller: Scroller = new Scroller(); @State closeInfoCarousel: boolean = false; - private cardList: number[] = [1, 2]; + private scroller: Scroller = new Scroller(); + private cardList: number[] = [1, 2, 3]; private windowClass: window.Window = AppStorage.get('windowClass')!; + private isHiding: boolean = false; @Provide('isFirstBulletBox') isFirstBulletBox: boolean = true; @Provide('popUpBoxIsShow') @Watch('bindSheetMonitor') popUpBoxIsShow: boolean = false; @Provide('currentStockPrice') currentStockPrice: number = 20; @@ -53,6 +55,12 @@ export struct StockDetailsView { @Provide('isExpand') isExpand: boolean = false; @State firstTabIndexSelected: number = 0; @State secondTabIndexSelected: number = 0; + @State topToolbar: number = new BreakpointType(56, 56, 62, 62, 62).getValue(this.currentWidthBreakpoint); + @State bottomToolbar: number = 78; + @State barOpacity: number = 1; + @State currentYOffset: number = 0; + @State topBlank: number = 18; + @State stockInForm: StockForm = STOCK_FORM[0]; bindSheetMonitor() { if (!this.popUpBoxIsShow) { @@ -63,13 +71,10 @@ export struct StockDetailsView { isOverlayMethod(statusBarColor: string): void { let SystemBarProperties: window.SystemBarProperties; SystemBarProperties = { statusBarColor: statusBarColor }; - try { - this.windowClass.setWindowSystemBarProperties(SystemBarProperties); - } catch (error) { - let err = error as BusinessError; + this.windowClass.setWindowSystemBarProperties(SystemBarProperties).catch((err: BusinessError) => { hilog.error(0x0000, 'StockDetailsView', `setWindowSystemBarProperties failed, error code=${err.code}, message=${err.message}`); - } + }); } @Builder @@ -84,7 +89,10 @@ export struct StockDetailsView { build() { NavDestination() { // Top toolbar - TopTitleBar() + Row() + .height((this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD) ? this.topBlank : 0) + TopTitleBar({ stockInForm: this.stockInForm }) .bindSheet($$this.popUpBoxIsShow, this.myBuilder(), { detents: [400], backgroundColor: '#F9F9F9', @@ -92,12 +100,14 @@ export struct StockDetailsView { maskColor: $r('sys.color.mask_fourth'), preferType: SheetType.CENTER }) + .height(this.topToolbar) + .opacity(this.barOpacity) // Content Area Scroll(this.scroller) { Column() { // Stock details information - StockDetailsInfo() + StockDetailsInfo({ stockInForm: this.stockInForm }) // Stock Notification Row() { @@ -130,8 +140,8 @@ export struct StockDetailsView { .backgroundColor(Color.White) .visibility(this.closeInfoCarousel ? Visibility.None : Visibility.Visible) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) .margin({ top: this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG ? 8 : 4 @@ -163,14 +173,13 @@ export struct StockDetailsView { Column() { // Stock candlestick chart area Row() { - LineChart({ model: this.lineChartModel }) + LineChart({ model: this.ChartViewModel.getLineChartModel() }) } // [StartExclude Stock_candlestick_chart_area] .height('80%') .padding({ top: 20 }) - // [EndExclude Stock_candlestick_chart_area] // Stock bar chart area @@ -180,7 +189,6 @@ export struct StockDetailsView { // [StartExclude Stock_candlestick_chart_area] .width('100%') .height('20%') - // [EndExclude Stock_candlestick_chart_area] } .height('100%') @@ -192,13 +200,13 @@ export struct StockDetailsView { StockDealDetails() } .width('100%') - .height(new BreakpointType(294, 286, 376).getValue(this.currentWidthBreakpoint)) + .height(new BreakpointType(294, 294, 286, 376, 376).getValue(this.currentWidthBreakpoint)) // [End Stock_candlestick_chart_area] .justifyContent(FlexAlign.SpaceBetween) .backgroundColor(Color.White) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) // Stock Circle @@ -232,8 +240,8 @@ export struct StockDetailsView { }, (item: number, index: number) => (index + item).toString()) } .margin({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) } } @@ -243,17 +251,49 @@ export struct StockDetailsView { .padding({ bottom: 8 }) - + .onScrollFrameBegin((offset: number) => { + if (!(this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD)) { + return { offsetRemain: offset }; + } + if (offset > 0) { + this.currentYOffset += offset; + if (this.currentYOffset <= 10) { + this.topToolbar = this.topToolbar * (1 - this.currentYOffset / 100); + this.bottomToolbar = this.bottomToolbar * (1 - this.currentYOffset / 100); + this.barOpacity = 1 - this.currentYOffset / 100; + } else { + this.topToolbar = 0; + this.bottomToolbar = 0; + this.barOpacity = 0; + this.topBlank = 0; + } + this.isHiding = true; + } + if (offset < 0 && this.isHiding) { + this.getUIContext().animateTo({ + duration: 600 + }, () => { + this.bottomToolbar = 78; + this.topToolbar = new BreakpointType(56, 56, 62, 62, 62).getValue(this.currentWidthBreakpoint) ; + this.barOpacity = 1; + this.currentYOffset = 0; + this.isHiding = false; + this.topBlank = 18; + }); + } + return { offsetRemain: offset }; + }) // [Start trading_operation_line] // Bottom toolbar Row() { Row({ space: 24 }) { - TitleIcon({ icon: $r('sys.symbol.dot_grid_2x2'), title: $r('app.string.self_selected_settings') }) - TitleIcon({ icon: $r('sys.symbol.Investment_stable_value_add'), title: $r('app.string.stock_pk') }) - TitleIcon({ icon: $r('sys.symbol.more'), title: $r('app.string.more') }) + TitleIcon($r('sys.symbol.dot_grid_2x2'), $r('app.string.self_selected_settings')) + TitleIcon($r('sys.symbol.Investment_stable_value_add'), $r('app.string.stock_pk')) + TitleIcon($r('sys.symbol.more'), $r('app.string.more')) } .margin({ - right: new BreakpointType(32, 101, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(32, 32, 101, 32, 32).getValue(this.currentWidthBreakpoint) }) Blank() @@ -288,15 +328,17 @@ export struct StockDetailsView { } // [End trading_operation_line] .width('100%') - .height(78) + .height(this.bottomToolbar) + .opacity(this.barOpacity) .backgroundColor($r('sys.color.font_on_primary')) .alignItems(VerticalAlign.Top) .justifyContent(this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG ? FlexAlign.End : FlexAlign.Start) .padding({ top: 6, - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) + .margin({ bottom: -6 }) .border({ width: { top: 0.5 }, color: { top: '#33000000' }, @@ -308,7 +350,8 @@ export struct StockDetailsView { .width('100%') .backgroundColor(Color.White) .padding({ - top: AppStorage.get('statusBarHeight') + top: this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? 0 : AppStorage.get('statusBarHeight') }) .onBackPressed(() => { if (this.tabletMode === NavigationMode.Stack) { @@ -317,5 +360,8 @@ export struct StockDetailsView { } return false; }) + .onReady((context) => { + this.stockInForm = context.pathInfo.param as StockForm; + }) } } \ No newline at end of file diff --git a/entry/src/main/ets/views/BuyPopUp.ets b/features/stockdetail/src/main/ets/views/BuyPopUp.ets similarity index 84% rename from entry/src/main/ets/views/BuyPopUp.ets rename to features/stockdetail/src/main/ets/views/BuyPopUp.ets index b9c227438eb5b3259595e5b73274f87e4e692b80..bfb70c1db8568c7473aa279742e0cfa54ccd3b74 100644 --- a/entry/src/main/ets/views/BuyPopUp.ets +++ b/features/stockdetail/src/main/ets/views/BuyPopUp.ets @@ -29,13 +29,13 @@ export struct BuyPopUp { Column({ space: 16 }) { Row() { Row() { - UniversalIcon({ - icon: $r('sys.symbol.chevron_left'), - iconBackgroundColor: $r('sys.color.comp_background_tertiary') + Row() { + UniversalIcon($r('sys.color.comp_background_tertiary'), $r('sys.symbol.chevron_left')) + } + .onClick(() => { + this.isFirstBulletBox = true; }) - .onClick(() => { - this.isFirstBulletBox = true; - }) + Column() { Text($r('app.string.buy')) .fontSize(20) @@ -51,18 +51,15 @@ export struct BuyPopUp { }) } - UniversalIcon({ - icon: $r('sys.symbol.xmark'), - iconBackgroundColor: $r('sys.color.comp_background_tertiary'), - fontSize: $r('sys.float.Title_S') + Row() { + UniversalIcon($r('sys.color.comp_background_tertiary'), $r('sys.symbol.xmark'), $r('sys.float.Title_S')) + } + .onClick(() => { + this.purchaseQuantity = 100; + this.buyIsShow = false; + this.popUpBoxIsShow = false; + this.isFirstBulletBox = true; }) - .onClick(() => { - this.sharesHeldNumber += this.purchaseQuantity; - this.purchaseQuantity = 100; - this.buyIsShow = false; - this.popUpBoxIsShow = false; - this.isFirstBulletBox = true; - }) } .justifyContent(FlexAlign.SpaceBetween) .width('100%') diff --git a/features/stockdetail/src/main/ets/views/CommonView.ets b/features/stockdetail/src/main/ets/views/CommonView.ets new file mode 100644 index 0000000000000000000000000000000000000000..d3070033c182925938477c61a21651a46c68d204 --- /dev/null +++ b/features/stockdetail/src/main/ets/views/CommonView.ets @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; +import { OTHER_TITLE, StockInForm } from '../models/DataModel'; + +@Builder +export function WordBackgroundComm(text: ResourceStr, textFontColor: ResourceColor, + textBackgroundColor: ResourceColor) { + Row() { + Text(text) + .fontSize(10) + .fontColor(textFontColor) + } + .width(12) + .height(12) + .borderRadius(2) + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.Center) + .backgroundColor(textBackgroundColor) + .margin({ + right: 4 + }) +} + +@Builder +export function UniversalIcon(iconBackgroundColor: ResourceColor, icon: Resource, + fontSize: ResourceColor = $r('sys.float.Title_L')) { + Button({ type: ButtonType.Circle }) { + SymbolGlyph(icon) + .fontColor([$r('sys.color.icon_primary')]) + .fontSize(fontSize) + } + .height(46) + .aspectRatio(1) + .backgroundColor(iconBackgroundColor) +} + +@Builder +export function StockDetails(title: ResourceStr = '', price: string = '', amount: number = 0, index: number = 0, + isShowNumber: boolean = true) { + Row() { + Text(title) { + Span(title) + if (isShowNumber) { + Span(index.toString()) + } + } + .textType() + .fontColor('#666666') + + Text(price) + .textType() + .fontColor(index % 2 === 0 ? '#FA4337' : '#1DB775') + Text(amount.toString()) + .textType() + .fontColor('#666666') + .alignSelf(ItemAlign.End) + } + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) +} + +@Builder +export function TitleIcon(icon?: Resource, title?: Resource) { + Column() { + SymbolGlyph(icon) + .fontColor([$r('sys.color.icon_primary')]) + .fontSize(24) + Text(title) + .fontSize(10) + .lineHeight(13) + .fontColor('#999999') + .margin({ + top: 4 + }) + } + .width(40) + .height(42) + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) +} + +@Component +export struct StockInFormList { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; + public item?: StockInForm; + public index: number = 0; + @Consume('isExpand') isExpand: boolean; + + build() { + Row() { + Column({ space: 3 }) { + Row() { + Text(this.item?.title1) + .textStocksTitle() + Text(this.item?.value1) + .fontColor(this.item?.color1) + .textStocksValue() + } + .textStocksTitleValue() + + Row() { + Text(this.item?.title2) + .textStocksTitle() + Text(this.item?.value2) + .fontColor(this.item?.color2) + .textStocksValue() + } + .textStocksTitleValue() + + Row() { + Text(this.item?.title3) + .textStocksTitle() + Text(this.item?.value3) + .fontColor(this.item?.color3) + .textStocksValue() + } + .textStocksTitleValue() + } + .padding({ + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) + }) + + Divider() + .vertical(true) + .height('85%') + .color('#979797') + .visibility(this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM ? + ((this.index + 1) % 2 === 0 ? Visibility.Hidden : Visibility.Visible) : + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_MD ? + ((this.index + 1) % 3 === 0 || this.index === 3 ? Visibility.Hidden : Visibility.Visible) : + ((this.index + 1) % 4 === 0 ? Visibility.Hidden : Visibility.Visible)) + } + .width('100%') + .height(51) + .margin({ + bottom: 6 + }) + .visibility(this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM ? + ((this.index + 1) > 2 ? (!this.isExpand ? Visibility.None : Visibility.Visible) : Visibility.Visible) : + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_MD ? + ((this.index + 1) > 3 ? (!this.isExpand ? Visibility.None : Visibility.Visible) : Visibility.Visible) : + ((this.index + 1) > 4 ? (!this.isExpand ? Visibility.None : Visibility.Visible) : Visibility.Visible)) + } +} + +@Component +export struct CommSlide { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; + @Prop tabIndexSelected: number = 0; + public commSlideData: ResourceStr[] = OTHER_TITLE; + + build() { + // [Start tab_sliding_area] + List({ + space: new BreakpointType(46, 46, 90, 150, 150).getValue(this.currentWidthBreakpoint) + }) { + ForEach(this.commSlideData, (item: string, index: number) => { + ListItem() { + Column() { + Text(item) + // [StartExclude tab_sliding_area] + .fontSize(16) + .fontWeight(this.tabIndexSelected === index ? 700 : 400) + .fontColor(this.tabIndexSelected === index ? '#000000' : '#999999') + .height(21) + .focusable(true) + .groupDefaultFocus(index === 0 ? true : false) + // [EndExclude tab_sliding_area] + } + } + .margin({ + top: 9, + right: this.commSlideData.length === index + 1 ? + new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) : 0, + left: index === 0 ? new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) : 0, + }) + .border({ + width: { + bottom: this.tabIndexSelected === index ? 2 : 0 + }, + color: { + bottom: this.tabIndexSelected === index ? '#FA4337' : '' + }, + style: { + bottom: BorderStyle.Solid + } + }) + .onClick(() => { + this.tabIndexSelected = index; + }) + }, (item: string, index: number) => (index + item).toString()) + } + .scrollBar(BarState.Off) + .listDirection(Axis.Horizontal) + // [End tab_sliding_area] + } +} + +@Extend(Text) +function textType() { + .fontWeight(FontWeight.Regular) + .fontSize(10) + .lineHeight(14) +} + +@Extend(Text) +function textStocksTitle() { + .fontSize(11) + .fontColor('#999999') +} + +@Extend(Text) +function textStocksValue() { + .fontSize(11) + .fontWeight(FontWeight.Medium) +} + +@Extend(Row) +function textStocksTitleValue() { + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) +} \ No newline at end of file diff --git a/entry/src/main/ets/views/MultiWindowEntryComponent.ets b/features/stockdetail/src/main/ets/views/MultiWindowEntryComponent.ets similarity index 100% rename from entry/src/main/ets/views/MultiWindowEntryComponent.ets rename to features/stockdetail/src/main/ets/views/MultiWindowEntryComponent.ets diff --git a/entry/src/main/ets/views/RegularWayPopUp.ets b/features/stockdetail/src/main/ets/views/RegularWayPopUp.ets similarity index 33% rename from entry/src/main/ets/views/RegularWayPopUp.ets rename to features/stockdetail/src/main/ets/views/RegularWayPopUp.ets index 98169a5d7c66ca0990e61acb258e8bad474adb69..bc42f51f6811e065c1f6a310e5a56ceaf969283b 100644 --- a/entry/src/main/ets/views/RegularWayPopUp.ets +++ b/features/stockdetail/src/main/ets/views/RegularWayPopUp.ets @@ -14,18 +14,20 @@ */ import { CounterComponent, CounterType } from '@kit.ArkUI'; -import { BreakpointType } from '../utils/BreakpointType'; +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; import { UniversalIcon } from './CommonView'; @Component export struct RegularWayPopUp { @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; + @StorageLink('currentHeightBreakpoint') currentHeightBreakpoint: number = 1; @StorageLink('sharesHeldNumber') sharesHeldNumber: number = 0; @Consume('isFirstBulletBox') isFirstBulletBox: boolean; @Consume('popUpBoxIsShow') popUpBoxIsShow: boolean; @Consume('currentStockPrice') currentStockPrice: number; @Consume('purchaseQuantity') purchaseQuantity: number; @Consume('buyIsShow') buyIsShow: boolean; + private scroller: Scroller = new Scroller(); build() { Column() { @@ -35,115 +37,122 @@ export struct RegularWayPopUp { .fontSize(20) .fontColor($r('sys.color.font_primary')) .fontWeight(FontWeight.Bold) - UniversalIcon({ - icon: $r('sys.symbol.xmark'), - iconBackgroundColor: $r('sys.color.comp_background_tertiary'), - fontSize: $r('sys.float.Title_S') + Row() { + UniversalIcon($r('sys.color.comp_background_tertiary'), $r('sys.symbol.xmark'), $r('sys.float.Title_S')) + } + .onClick(() => { + this.purchaseQuantity = 100; + this.buyIsShow = false; + this.popUpBoxIsShow = false; + this.isFirstBulletBox = true; }) - .onClick(() => { - this.sharesHeldNumber += this.purchaseQuantity; - this.purchaseQuantity = 100; - this.buyIsShow = false; - this.popUpBoxIsShow = false; - this.isFirstBulletBox = true; - }) } .justifyContent(FlexAlign.SpaceBetween) .width('100%') .height(60) - Row() { - Text($r('app.string.Stock_name_code')) - Text($r('app.string.shareholder_account')) - } - .width('100%') - .justifyContent(FlexAlign.SpaceBetween) + Scroll(this.scroller) { + Column({ space: + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? 6 : 16 + }) { + Row() { + Text($r('app.string.Stock_name_code')) + Text($r('app.string.shareholder_account')) + } + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) - Row() { - CounterComponent({ - options: { - type: CounterType.LIST, - numberOptions: { - label: $r('app.string.price'), - value: this.currentStockPrice, - step: 1, - onChange: (value: number) => { - this.currentStockPrice = value; + Row() { + CounterComponent({ + options: { + type: CounterType.LIST, + numberOptions: { + label: $r('app.string.price'), + value: this.currentStockPrice, + step: 1, + onChange: (value: number) => { + this.currentStockPrice = value; + } + } } - } + }) } - }) - } - .width('100%') - .height(48) - .backgroundColor(Color.White) - .borderRadius(16) + .width('100%') + .height(48) + .backgroundColor(Color.White) + .borderRadius(16) - Row() { - Text() { - Span($r('app.string.limit_down')) - .fontColor('#707070') - Span(`${(this.currentStockPrice * (1 - 0.1)).toFixed(2)}`) - .fontColor('#1DB775') - Span($r('app.string.raising_limit')) - .fontColor('#707070') - Span(`${(this.currentStockPrice * (1 + 0.1)).toFixed(2)}`) - .fontColor('#FA4337') - } - .fontSize(11) - } - .width('100%') - .justifyContent(FlexAlign.Start) - .padding({ - right: 8, - left: 8 - }) + Row() { + Text() { + Span($r('app.string.limit_down')) + .fontColor('#707070') + Span(`${(this.currentStockPrice * (1 - 0.1)).toFixed(2)}`) + .fontColor('#1DB775') + Span($r('app.string.raising_limit')) + .fontColor('#707070') + Span(`${(this.currentStockPrice * (1 + 0.1)).toFixed(2)}`) + .fontColor('#FA4337') + } + .fontSize(11) + } + .width('100%') + .justifyContent(FlexAlign.Start) + .padding({ + right: 8, + left: 8 + }) - Row() { - CounterComponent({ - options: { - type: CounterType.LIST, - numberOptions: { - label: $r('app.string.quantity'), - min: 0, - value: 100, - max: 100 * 1000, - step: 100, - onChange: (value: number) => { - this.purchaseQuantity = value; + Row() { + CounterComponent({ + options: { + type: CounterType.LIST, + numberOptions: { + label: $r('app.string.quantity'), + min: 0, + value: 100, + max: 100 * 1000, + step: 100, + onChange: (value: number) => { + this.purchaseQuantity = value; + } + } } - } + }) } - }) - } - .width('100%') - .height(48) - .backgroundColor(Color.White) - .borderRadius(16) + .width('100%') + .height(48) + .backgroundColor(Color.White) + .borderRadius(16) - Row() { - Text() { - Span($r('app.string.already_held')) - Span(` ${this.sharesHeldNumber} `).fontColor($r('sys.color.alert')) - Span($r('app.string.stock')) - } - .fontSize(11) + Row() { + Text() { + Span($r('app.string.already_held')) + Span(` ${this.sharesHeldNumber} `).fontColor($r('sys.color.alert')) + Span($r('app.string.stock')) + } + .fontSize(11) - Text() { - Span($r('app.string.buy_able')) - Span(' 0 ').fontColor($r('sys.color.alert')) - Span($r('app.string.stock')) + Text() { + Span($r('app.string.buy_able')) + Span(' 0 ').fontColor($r('sys.color.alert')) + Span($r('app.string.stock')) + } + .fontSize(11) + } + .width('100%') + .justifyContent(FlexAlign.SpaceBetween) + .padding({ + right: 8, + bottom: this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? 6 : 0, + left: 8 + }) } - .fontSize(11) + .width('100%') } - .width('100%') - .justifyContent(FlexAlign.SpaceBetween) - .padding({ - right: 8, - left: 8 - }) + .scrollBar(BarState.Off) } - .width('100%') Row() { Text($r('app.string.buy')) @@ -156,8 +165,14 @@ export struct RegularWayPopUp { .backgroundColor('#E53137') .justifyContent(FlexAlign.Center) .padding({ - right: new BreakpointType(16, 0, 0).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 0, 0).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 0, 0, 0).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 0, 0, 0).getValue(this.currentWidthBreakpoint) + }) + .margin({ + bottom: + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + (this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD || + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_SM) ? 80 : 10 }) .onClick(() => { if (this.purchaseQuantity > 0) { @@ -166,13 +181,17 @@ export struct RegularWayPopUp { } }) } - .justifyContent(FlexAlign.SpaceBetween) + .justifyContent( + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? FlexAlign.Start : FlexAlign.SpaceBetween + ) .width('100%') .height('100%') .padding({ top: 12, right: 16, - bottom: 32, + bottom: this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD ? 0 : 32, left: 16 }) } diff --git a/entry/src/main/ets/views/StockDealDetails.ets b/features/stockdetail/src/main/ets/views/StockDealDetails.ets similarity index 63% rename from entry/src/main/ets/views/StockDealDetails.ets rename to features/stockdetail/src/main/ets/views/StockDealDetails.ets index 5ce09ac1fc941b1eef9b0ef5d5886ce2a952259e..1638f7bef0321beffa6331b6bb223f7943760eb0 100644 --- a/entry/src/main/ets/views/StockDealDetails.ets +++ b/features/stockdetail/src/main/ets/views/StockDealDetails.ets @@ -13,8 +13,8 @@ * limitations under the License. */ +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; import { BUY_SELL_SHARES, SELL_SHARES, SUBMISSION_TIME, transactionDetails } from '../models/DataModel'; -import { BreakpointType } from '../utils/BreakpointType'; import { StockDetails } from './CommonView'; @Component @@ -33,16 +33,13 @@ export struct StockDealDetails { .fontSize(10) .textAlign(TextAlign.Center) ForEach(SELL_SHARES, (item: transactionDetails, index: number) => { - StockDetails({ - title: item.title, - price: item.price, - amount: item.amount, - index: index + 1 + Row() { + StockDetails(item.title, item.price, item.amount, index + 1) + } + .padding({ + right: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint) }) - .padding({ - right: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint) - }) }, (item: transactionDetails, index: number) => (item.price + index).toString()) Row() { Slider({ @@ -58,16 +55,13 @@ export struct StockDealDetails { .height(10) ForEach(BUY_SELL_SHARES, (item: transactionDetails, index: number) => { - StockDetails({ - title: item.title, - price: item.price, - amount: item.amount, - index: index + 1 + Row() { + StockDetails(item.title, item.price, item.amount, index + 1) + } + .padding({ + right: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint) }) - .padding({ - right: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint) - }) }, (item: transactionDetails, index: number) => (item.price + index).toString()) Text($r('app.string.transaction_details')) @@ -80,23 +74,19 @@ export struct StockDealDetails { Scroll(this.concludeDetailsScroller) { Column() { ForEach(SUBMISSION_TIME, (item: transactionDetails, index: number) => { - StockDetails({ - title: item.title, - price: item.price, - amount: item.amount, - isShowNumber: false, - index: index + 1 + Row() { + StockDetails(item.title, item.price, item.amount, index + 1, false) + } + .padding({ + top: 2, + right: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint), + bottom: 2, + left: new BreakpointType(8.25, 8.25, 8.25, 9, 9).getValue(this.currentWidthBreakpoint) }) - .padding({ - top: 2, - right: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint), - bottom: 2, - left: new BreakpointType(8.25, 8.25, 9).getValue(this.currentWidthBreakpoint) - }) }, (item: transactionDetails, index: number) => (item.price + index).toString()) } } - .height(new BreakpointType(70, 70, 102).getValue(this.currentWidthBreakpoint)) + .height(new BreakpointType(70, 70, 70, 102, 102).getValue(this.currentWidthBreakpoint)) .scrollBar(BarState.Off) } .height('100%') @@ -107,7 +97,7 @@ export struct StockDealDetails { bottom: 12 }) } - .width(new BreakpointType(103, 103, 192).getValue(this.currentWidthBreakpoint)) + .width(new BreakpointType(103, 103, 103, 192, 192).getValue(this.currentWidthBreakpoint)) .height('100%') .padding({ left: 4 diff --git a/entry/src/main/ets/views/StockDetailsInfo.ets b/features/stockdetail/src/main/ets/views/StockDetailsInfo.ets similarity index 83% rename from entry/src/main/ets/views/StockDetailsInfo.ets rename to features/stockdetail/src/main/ets/views/StockDetailsInfo.ets index ab4eefd3b606aee9392cb9f5ef8d2e3fbcf62695..46e2de94a69f06850cac176aefcbe10f5071c594 100644 --- a/entry/src/main/ets/views/StockDetailsInfo.ets +++ b/features/stockdetail/src/main/ets/views/StockDetailsInfo.ets @@ -13,19 +13,20 @@ * limitations under the License. */ -import { StockInForm, STOCK_INFORM_LIST } from '../models/DataModel'; -import { BreakpointType } from '../utils/BreakpointType'; +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; +import { StockForm, StockInForm, STOCK_FORM, STOCK_INFORM_LIST } from '../models/DataModel'; import { StockInFormList } from './CommonView'; @Component export struct StockDetailsInfo { @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; @Consume('isExpand') isExpand: boolean; + @State stockInForm: StockForm = STOCK_FORM[0]; build() { Column() { Row() { - Text('20.01') + Text(`${this.stockInForm.latestPrice / 100}`) .fontSize(30) .height(30) .fontColor('#FA4337') @@ -33,7 +34,7 @@ export struct StockDetailsInfo { .margin({ right: 11.5 }) - Text('+19.8 +0.64%') + Text(`${this.stockInForm.highsAndLows} ${this.stockInForm.priceLimit}`) .fontSize(14) .height(19) .fontColor('#FA4337') @@ -46,9 +47,9 @@ export struct StockDetailsInfo { .backgroundColor(Color.White) .padding({ top: 9, - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), bottom: 9, - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) // [Start market_quote_data_area] diff --git a/features/stockdetail/src/main/ets/views/StockTable.ets b/features/stockdetail/src/main/ets/views/StockTable.ets new file mode 100644 index 0000000000000000000000000000000000000000..5d9f703482001f77015dd07d74934238efab77c8 --- /dev/null +++ b/features/stockdetail/src/main/ets/views/StockTable.ets @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; +import { StockForm, STOCK_FORM, STOCK_TITLE } from '../models/DataModel'; +import { WordBackgroundComm } from './CommonView'; + +@Component +export struct StockTable { + @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; + @Consume('pageInfos') pageInfos: NavPathStack; + @Consume('tabletMode') tabletMode: NavigationMode; + private scroller: Scroller = new Scroller(); + + @Builder + StickyHeader(): void { + Row() { + ForEach(STOCK_TITLE, (item: Resource, index: number) => { + Row() { + Text(item) + .fontSize(12) + } + .justifyContent(index === 0 ? FlexAlign.Start : FlexAlign.End) + .width(index === 1 || index === 2 || index === 3 ? 90 : 100) + .padding({ + right: index === STOCK_TITLE.length - 1 ? + (new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint)) : 0, + left: index === 0 ? (new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint)) : 0 + }) + + }, (item: Resource, index: number) => item.toString() + index) + } + .height(36) + .backgroundColor(Color.White) + } + + build() { + // [Start stock_list_area] + Scroll(this.scroller) { + List({ space: 20, initialIndex: 0 }) { + ListItemGroup({ header: this.StickyHeader() }) { + // [StartExclude stock_list_area] + ListItem() { + } + // [EndExclude stock_list_area] + ForEach(STOCK_FORM, (item: StockForm) => { + ListItem() { + Row() { + Column() { + Text(item.title) + // [StartExclude stock_list_area] + .minFontSize(8) + .maxFontSize(16) + .height(21) + .width(64) + .maxLines(1) + + Row() { + Text(item.stockNumber) + .fontSize(12) + .height(16) + .fontColor($r('sys.color.font_tertiary')) + .textAlign(TextAlign.Start) + WordBackgroundComm(item.plate, item.plateFontColor, item.plateBackgroundColor) + } + .width(64) + .justifyContent(FlexAlign.SpaceBetween) + + // [EndExclude stock_list_area] + } + .alignItems(HorizontalAlign.Start) + // [StartExclude stock_list_area] + .width(100) + .padding({ + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) + }) + + Text((item.latestPrice / 100).toString()) + .fontSize(14) + .height(19) + .width(90) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text((item.highsAndLows > 0 ? '+' + item.highsAndLows : item.highsAndLows).toString()) + .fontSize(14) + .height(19) + .width(90) + .fontColor(item.highsAndLows > 0 ? '#FA4337' : '#1DB775') + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text(item.priceLimit) + .fontSize(14) + .height(19) + .width(90) + .fontColor(item.highsAndLows > 0 ? '#FA4337' : '#1DB775') + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text(item.gross) + .fontSize(14) + .height(19) + .width(100) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text(item.impressions) + .fontSize(14) + .height(19) + .width(100) + .fontColor(item.highsAndLows > 0 ? '#FA4337' : '#1DB775') + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text() { + Span(item.volumeTransaction) + Span($r('app.string.billion')) + } + .fontSize(14) + .height(19) + .width(100) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + + Text(item.amplitude) + .fontSize(14) + .height(19) + .width(100) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text(item.changeHands) + .fontSize(14) + .height(19) + .width(100) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + Text(item.PEG.toString()) + .fontSize(14) + .height(19) + .width(100) + .textAlign(TextAlign.End) + .fontWeight(FontWeight.Medium) + // [EndExclude stock_list_area] + Text(item.PB.toString()) + .textAlign(TextAlign.End) + // [StartExclude stock_list_area] + .fontSize(14) + .height(19) + .width(100) + .fontWeight(FontWeight.Medium) + .padding({ + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) + }) + // [EndExclude stock_list_area] + } + } + .height(56) + }, (item: StockForm, index: number) => (item.latestPrice + index).toString()) + // [StartExclude stock_list_area] + ListItem() { + } + // [EndExclude stock_list_area] + } + .backgroundColor(Color.White) + .divider({ strokeWidth: 1, color: '#F2RDED' }) // The dividing line between each row + } + .scrollBar(BarState.Off) + .sticky(StickyStyle.Header) + } + .scrollable(ScrollDirection.Horizontal) // Rolling direction: vertical + .scrollBar(BarState.Off) // Permanent display of the scroll bar + // [End stock_list_area] + } +} \ No newline at end of file diff --git a/entry/src/main/ets/views/TopTitleBar.ets b/features/stockdetail/src/main/ets/views/TopTitleBar.ets similarity index 49% rename from entry/src/main/ets/views/TopTitleBar.ets rename to features/stockdetail/src/main/ets/views/TopTitleBar.ets index 40077879271729fc2ec4bec6d838e406c681ff59..808fdd464238a023dcbddf89f1f50583de399d24 100644 --- a/entry/src/main/ets/views/TopTitleBar.ets +++ b/features/stockdetail/src/main/ets/views/TopTitleBar.ets @@ -13,26 +13,47 @@ * limitations under the License. */ -import { Want } from '@kit.AbilityKit'; +import { Callback, emitter } from '@kit.BasicServicesKit'; +import { common, Want } from '@kit.AbilityKit'; import { TextModifier } from '@kit.ArkUI'; import { UniversalIcon, WordBackgroundComm } from './CommonView'; -import { BreakpointType } from '../utils/BreakpointType'; +import { BreakpointType } from 'base/src/main/ets/utils/BreakpointType'; import { MultiWindowEntryComponent } from './MultiWindowEntryComponent'; +import Logger from 'base/src/main/ets/utils/Logger'; +import { StockForm, STOCK_FORM } from '../models/DataModel'; @Component export struct TopTitleBar { + @LocalStorageLink('SplitScreenMode') SplitScreenMode: boolean = true; @StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: number = 1; + @StorageLink('currentHeightBreakpoint') currentHeightBreakpoint: number = 1; @StorageLink('lastWidthBreakpoint') lastWidthBreakpoint: number = 1; @StorageLink('isSplitScreen') isSplitScreen: boolean = false; + @StorageLink('isHideSplitScreen') isHideSplitScreen: boolean = false; @Consume('pageInfos') pageInfos: NavPathStack; @Consume('tabletMode') tabletMode: NavigationMode; @State textModifier: TextModifier = new TextModifier(); @State splitScreenWant: Want = { // Modify the bundleName, moduleName and abilityName of the current application, and launch the UIAbility within the application. bundleName: 'com.example.multiticketclass', - moduleName: 'entry', - abilityName: 'EntryAbility', + moduleName: 'phone', + abilityName: 'SplitScreenAbility', }; + private context = this.getUIContext().getHostContext() as common.UIAbilityContext; + @State stockInForm: StockForm = STOCK_FORM[0]; + + aboutToAppear(): void { + if (this.context.abilityInfo.name === 'EntryAbility') { + let innerEvent: emitter.InnerEvent = { + eventId: 1 + }; + let callBack: Callback = (eventData: emitter.EventData) => { + Logger.info(`eventData:${eventData}`); + this.pageInfos.pop(); + }; + emitter.on(innerEvent, callBack); + } + } build() { // [Start top_title_bar_area] @@ -40,28 +61,26 @@ export struct TopTitleBar { // The icon area on the left Row() { if (this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG && this.tabletMode === NavigationMode.Split) { - UniversalIcon({ - icon: $r('sys.symbol.arrow_up_left_and_arrow_down_right'), - iconBackgroundColor: $r('sys.color.comp_background_tertiary') - }) + Row() { + UniversalIcon($r('sys.color.comp_background_tertiary'), $r('sys.symbol.arrow_up_left_and_arrow_down_right')) + } // [StartExclude top_title_bar_area] - .onClick(() => { - this.tabletMode = NavigationMode.Stack; - }) + .onClick(() => { + this.tabletMode = NavigationMode.Stack; + }) // [EndExclude top_title_bar_area] } else { - UniversalIcon({ - icon: $r('sys.symbol.chevron_left'), - iconBackgroundColor: $r('sys.color.comp_background_tertiary') - }) + Row() { + UniversalIcon($r('sys.color.comp_background_tertiary'), $r('sys.symbol.chevron_backward')) + } // [StartExclude top_title_bar_area] - .onClick(() => { - if (this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG) { - this.tabletMode = NavigationMode.Split; - } else { - this.pageInfos.pop(); - } - }) + .onClick(() => { + if (this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG) { + this.tabletMode = NavigationMode.Split; + } else { + this.pageInfos.pop(); + } + }) // [EndExclude top_title_bar_area] } } @@ -71,21 +90,19 @@ export struct TopTitleBar { // The central title area at the top Column() { // [StartExclude top_title_bar_area] - Text($r('app.string.some_company_technology')) + Text(){ + Span(this.stockInForm.title) + Span(`(${this.stockInForm.stockNumber})`) + } .fontSize(16) .height(21) Row() { - WordBackgroundComm({ - text: $r('app.string.deep'), - textFontColor: '#1E6CF3', - textBackgroundColor: '#E8F0FE' - }) + WordBackgroundComm($r('app.string.deep'), '#1E6CF3', '#E8F0FE') Text($r('app.string.closed_day')) .fontSize(11) .height(15) .fontColor('#999999') } - // [EndExclude top_title_bar_area] } .height(40) @@ -101,15 +118,23 @@ export struct TopTitleBar { want: this.splitScreenWant }) } + .visibility((this.context.abilityInfo.name === 'EntryAbility' && + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM && this.isSplitScreen) || + (this.context.abilityInfo.name === 'EntryAbility' && + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_LG && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_SM) || + (this.context.abilityInfo.name === 'EntryAbility' && + this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_MD && + this.currentHeightBreakpoint === HeightBreakpoint.HEIGHT_MD) ? Visibility.Visible : Visibility.Hidden) } } // [End top_title_bar_area] .width('100%') - .height(new BreakpointType(56, 62, 62).getValue(this.currentWidthBreakpoint)) + .height(new BreakpointType(56, 56, 62, 62, 62).getValue(this.currentWidthBreakpoint)) .backgroundColor(Color.White) .padding({ - right: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint), - left: new BreakpointType(16, 24, 32).getValue(this.currentWidthBreakpoint) + right: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint), + left: new BreakpointType(16, 16, 24, 32, 32).getValue(this.currentWidthBreakpoint) }) } } \ No newline at end of file diff --git a/features/stockdetail/src/main/module.json5 b/features/stockdetail/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d86837c3f8e34984532743d547291b36eafaf7eb --- /dev/null +++ b/features/stockdetail/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "stockdetail", + "type": "har", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ] + } +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/element/color.json b/features/stockdetail/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/features/stockdetail/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/features/stockdetail/src/main/resources/base/element/float.json b/features/stockdetail/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/features/stockdetail/src/main/resources/base/element/string.json b/features/stockdetail/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..92e8998bfb6a9396444530b3e09d69cc2f9f34a7 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/element/string.json @@ -0,0 +1,352 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "StockDetailAbility_desc", + "value": "description" + }, + { + "name": "StockDetailAbility_label", + "value": "MultiStockCategoryApp" + }, + { + "name": "regular_way", + "value": "Regular Way" + }, + { + "name": "self_selected_settings", + "value": "Settings" + }, + { + "name": "stock_pk", + "value": "StockPK" + }, + { + "name": "more", + "value": "More" + }, + { + "name": "go_trade", + "value": "Go Trade" + }, + { + "name": "transaction_details", + "value": "Transaction Details" + }, + { + "name": "market_conditions", + "value": "Market Conditions" + }, + { + "name": "information", + "value": "Information" + }, + { + "name": "announcement", + "value": "XX Technology:Latest announcement." + }, + { + "name": "closed_day", + "value": "Closed at 15:03:03 on October 19th" + }, + { + "name": "some_company_technology", + "value": "Some Company Technology" + }, + { + "name": "deep", + "value": "S" + }, + { + "name": "confirm_purchase", + "value": "Confirm Purchase" + }, + { + "name": "order_quantity", + "value": "Order quantity" + }, + { + "name": "commissioned_price", + "value": "Commissioned Price" + }, + { + "name": "shareholder_account", + "value": "Account: 500****5" + }, + { + "name": "buy", + "value": "Buy" + }, + { + "name": "Stock_name_code", + "value": "Company 3****3" + }, + { + "name": "quantity", + "value": "Quantity" + }, + { + "name": "price", + "value": "Price" + }, + { + "name": "limit_down", + "value": "Limit Down " + }, + { + "name": "raising_limit", + "value": " Raising Limit " + }, + { + "name": "already_held", + "value": "Already Held" + }, + { + "name": "stock", + "value": "stock" + }, + { + "name": "buy_able", + "value": "BuyAble" + }, + { + "name": "stock_name", + "value": "Stock Name" + }, + { + "name": "stock_number", + "value": "Stock Number" + }, + { + "name": "latest_price", + "value": "Latest Price" + }, + { + "name": "highs_and_lows", + "value": "High Low" + }, + { + "name": "price_limit", + "value": "Price Limit" + }, + { + "name": "gross", + "value": "Gross" + }, + { + "name": "impressions", + "value": "Impressions" + }, + { + "name": "volume_transaction", + "value": "Volume Business" + }, + { + "name": "amplitude", + "value": "Amplitude" + }, + { + "name": "change_hands", + "value": "Change Hands" + }, + { + "name": "PEG", + "value": "PEG" + }, + { + "name": "PB", + "value": "PB" + }, + { + "name": "somebody_technology", + "value": "Technology" + }, + { + "name": "certain_estate_company", + "value": "Real Estate" + }, + { + "name": "certain_pharmaceutical_company", + "value": "Pharmacy" + }, + { + "name": "billion", + "value": "B" + }, + { + "name": "growth_enterprise_market", + "value": "G" + }, + { + "name": "securities_margin_trading", + "value": "S" + }, + { + "name": "certain_index", + "value": "Certain Index" + }, + { + "name": "deep_number", + "value": "Deep Number" + }, + { + "name": "science_technology", + "value": "Technology" + }, + { + "name": "self_select_stock", + "value": "Self Select Stock" + }, + { + "name": "all", + "value": "All" + }, + { + "name": "add_custom_options", + "value": "Add custom options" + }, + { + "name": "optional", + "value": "Optional" + }, + { + "name": "market", + "value": "Market" + }, + { + "name": "stock_company", + "value": "XX Stock" + }, + { + "name": "stock_text_start", + "value": "xxxx xxxx" + }, + { + "name": "stock_text_end", + "value": "xxxx xxxx" + }, + { + "name": "stock_names", + "value": "Stock Name" + }, + { + "name": "home_page", + "value": "Home Page" + }, + { + "name": "time_share", + "value": "Time Share" + }, + { + "name": "five_days", + "value": "Five Days" + }, + { + "name": "daily_k", + "value": "Daily K" + }, + { + "name": "week_k", + "value": "Week K" + }, + { + "name": "month_k", + "value": "Month K" + }, + { + "name": "season_k", + "value": "Season K" + }, + { + "name": "half_year_k", + "value": "Half Year K" + }, + { + "name": "year_k", + "value": "Year K" + }, + { + "name": "discussion", + "value": "Discussion" + }, + { + "name": "must_read", + "value": "Must Read" + }, + { + "name": "capital", + "value": "Capital" + }, + { + "name": "datum", + "value": "Datum" + }, + { + "name": "announcements", + "value": "Announcement" + }, + { + "name": "finance", + "value": "Finance" + }, + { + "name": "research_report", + "value": "Research Report" + }, + { + "name": "related_fund", + "value": "Related Fund" + }, + { + "name": "now_begins", + "value": "Now Begins" + }, + { + "name": "yesterday_close", + "value": "Yesterday Close" + }, + { + "name": "turnover_rate", + "value": "Turnover Rate" + }, + { + "name": "tallest", + "value": "tallest" + }, + { + "name": "lowest", + "value": "lowest" + }, + { + "name": "turnover", + "value": "turnover" + }, + { + "name": "total_value", + "value": "Total Value" + }, + { + "name": "text_hands", + "value": "4570H" + }, + { + "name": "text_billion", + "value": "26.10Y" + }, + { + "name": "turnover_value", + "value": "910.5W" + }, + { + "name": "sell", + "value": "Sell" + }, + { + "name": "text_buy", + "value": "Buy" + } + ] +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/background.png b/features/stockdetail/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/background.png differ diff --git a/features/stockdetail/src/main/resources/base/media/doc_plaintext_fill.svg b/features/stockdetail/src/main/resources/base/media/doc_plaintext_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..613f2b2d62b9b3ca11d616643dd41e2690fce0d0 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/media/doc_plaintext_fill.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/doc_text_fill.svg b/features/stockdetail/src/main/resources/base/media/doc_text_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..a27271d0d50f5da0501823799c0a934281f5db38 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/media/doc_text_fill.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/foreground.png b/features/stockdetail/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/foreground.png differ diff --git a/features/stockdetail/src/main/resources/base/media/house_fill.svg b/features/stockdetail/src/main/resources/base/media/house_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..1d3f8d62884c7261b357c20b1752ba3343d215e8 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/media/house_fill.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/layered_image.json b/features/stockdetail/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/features/stockdetail/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/rectangle_split_2x1.png b/features/stockdetail/src/main/resources/base/media/rectangle_split_2x1.png new file mode 100644 index 0000000000000000000000000000000000000000..3f097498e5f160b9d9c652b630a08df57e72c7f8 Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/rectangle_split_2x1.png differ diff --git a/features/stockdetail/src/main/resources/base/media/split_screen.png b/features/stockdetail/src/main/resources/base/media/split_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..4438e1285ede8761849a81d20cba9973c8eff4f4 Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/split_screen.png differ diff --git a/features/stockdetail/src/main/resources/base/media/square_and_pencil_fill.svg b/features/stockdetail/src/main/resources/base/media/square_and_pencil_fill.svg new file mode 100644 index 0000000000000000000000000000000000000000..2e6d18e94b304d18f85413c265a2f1502a4e3a5a --- /dev/null +++ b/features/stockdetail/src/main/resources/base/media/square_and_pencil_fill.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/media/startIcon.png b/features/stockdetail/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/startIcon.png differ diff --git a/features/stockdetail/src/main/resources/base/media/stocks_pk.png b/features/stockdetail/src/main/resources/base/media/stocks_pk.png new file mode 100644 index 0000000000000000000000000000000000000000..57a1cc0a94a6698ee47c3e4658843aec1dc09b13 Binary files /dev/null and b/features/stockdetail/src/main/resources/base/media/stocks_pk.png differ diff --git a/features/stockdetail/src/main/resources/base/profile/backup_config.json b/features/stockdetail/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/features/stockdetail/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/base/profile/main_pages.json b/features/stockdetail/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..c9b2f5bc1287643784184b6a16ca7421a2bd2d80 --- /dev/null +++ b/features/stockdetail/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/StockDetailsPage" + ] +} diff --git a/features/stockdetail/src/main/resources/dark/element/color.json b/features/stockdetail/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/features/stockdetail/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/en_US/element/string.json b/features/stockdetail/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..92e8998bfb6a9396444530b3e09d69cc2f9f34a7 --- /dev/null +++ b/features/stockdetail/src/main/resources/en_US/element/string.json @@ -0,0 +1,352 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "StockDetailAbility_desc", + "value": "description" + }, + { + "name": "StockDetailAbility_label", + "value": "MultiStockCategoryApp" + }, + { + "name": "regular_way", + "value": "Regular Way" + }, + { + "name": "self_selected_settings", + "value": "Settings" + }, + { + "name": "stock_pk", + "value": "StockPK" + }, + { + "name": "more", + "value": "More" + }, + { + "name": "go_trade", + "value": "Go Trade" + }, + { + "name": "transaction_details", + "value": "Transaction Details" + }, + { + "name": "market_conditions", + "value": "Market Conditions" + }, + { + "name": "information", + "value": "Information" + }, + { + "name": "announcement", + "value": "XX Technology:Latest announcement." + }, + { + "name": "closed_day", + "value": "Closed at 15:03:03 on October 19th" + }, + { + "name": "some_company_technology", + "value": "Some Company Technology" + }, + { + "name": "deep", + "value": "S" + }, + { + "name": "confirm_purchase", + "value": "Confirm Purchase" + }, + { + "name": "order_quantity", + "value": "Order quantity" + }, + { + "name": "commissioned_price", + "value": "Commissioned Price" + }, + { + "name": "shareholder_account", + "value": "Account: 500****5" + }, + { + "name": "buy", + "value": "Buy" + }, + { + "name": "Stock_name_code", + "value": "Company 3****3" + }, + { + "name": "quantity", + "value": "Quantity" + }, + { + "name": "price", + "value": "Price" + }, + { + "name": "limit_down", + "value": "Limit Down " + }, + { + "name": "raising_limit", + "value": " Raising Limit " + }, + { + "name": "already_held", + "value": "Already Held" + }, + { + "name": "stock", + "value": "stock" + }, + { + "name": "buy_able", + "value": "BuyAble" + }, + { + "name": "stock_name", + "value": "Stock Name" + }, + { + "name": "stock_number", + "value": "Stock Number" + }, + { + "name": "latest_price", + "value": "Latest Price" + }, + { + "name": "highs_and_lows", + "value": "High Low" + }, + { + "name": "price_limit", + "value": "Price Limit" + }, + { + "name": "gross", + "value": "Gross" + }, + { + "name": "impressions", + "value": "Impressions" + }, + { + "name": "volume_transaction", + "value": "Volume Business" + }, + { + "name": "amplitude", + "value": "Amplitude" + }, + { + "name": "change_hands", + "value": "Change Hands" + }, + { + "name": "PEG", + "value": "PEG" + }, + { + "name": "PB", + "value": "PB" + }, + { + "name": "somebody_technology", + "value": "Technology" + }, + { + "name": "certain_estate_company", + "value": "Real Estate" + }, + { + "name": "certain_pharmaceutical_company", + "value": "Pharmacy" + }, + { + "name": "billion", + "value": "B" + }, + { + "name": "growth_enterprise_market", + "value": "G" + }, + { + "name": "securities_margin_trading", + "value": "S" + }, + { + "name": "certain_index", + "value": "Certain Index" + }, + { + "name": "deep_number", + "value": "Deep Number" + }, + { + "name": "science_technology", + "value": "Technology" + }, + { + "name": "self_select_stock", + "value": "Self Select Stock" + }, + { + "name": "all", + "value": "All" + }, + { + "name": "add_custom_options", + "value": "Add custom options" + }, + { + "name": "optional", + "value": "Optional" + }, + { + "name": "market", + "value": "Market" + }, + { + "name": "stock_company", + "value": "XX Stock" + }, + { + "name": "stock_text_start", + "value": "xxxx xxxx" + }, + { + "name": "stock_text_end", + "value": "xxxx xxxx" + }, + { + "name": "stock_names", + "value": "Stock Name" + }, + { + "name": "home_page", + "value": "Home Page" + }, + { + "name": "time_share", + "value": "Time Share" + }, + { + "name": "five_days", + "value": "Five Days" + }, + { + "name": "daily_k", + "value": "Daily K" + }, + { + "name": "week_k", + "value": "Week K" + }, + { + "name": "month_k", + "value": "Month K" + }, + { + "name": "season_k", + "value": "Season K" + }, + { + "name": "half_year_k", + "value": "Half Year K" + }, + { + "name": "year_k", + "value": "Year K" + }, + { + "name": "discussion", + "value": "Discussion" + }, + { + "name": "must_read", + "value": "Must Read" + }, + { + "name": "capital", + "value": "Capital" + }, + { + "name": "datum", + "value": "Datum" + }, + { + "name": "announcements", + "value": "Announcement" + }, + { + "name": "finance", + "value": "Finance" + }, + { + "name": "research_report", + "value": "Research Report" + }, + { + "name": "related_fund", + "value": "Related Fund" + }, + { + "name": "now_begins", + "value": "Now Begins" + }, + { + "name": "yesterday_close", + "value": "Yesterday Close" + }, + { + "name": "turnover_rate", + "value": "Turnover Rate" + }, + { + "name": "tallest", + "value": "tallest" + }, + { + "name": "lowest", + "value": "lowest" + }, + { + "name": "turnover", + "value": "turnover" + }, + { + "name": "total_value", + "value": "Total Value" + }, + { + "name": "text_hands", + "value": "4570H" + }, + { + "name": "text_billion", + "value": "26.10Y" + }, + { + "name": "turnover_value", + "value": "910.5W" + }, + { + "name": "sell", + "value": "Sell" + }, + { + "name": "text_buy", + "value": "Buy" + } + ] +} \ No newline at end of file diff --git a/features/stockdetail/src/main/resources/zh_CN/element/string.json b/features/stockdetail/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f06c74aedcc41ead0dc5146a7042f6e26732d1e4 --- /dev/null +++ b/features/stockdetail/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,352 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "StockDetailAbility_desc", + "value": "description" + }, + { + "name": "StockDetailAbility_label", + "value": "一多股票类应用" + }, + { + "name": "regular_way", + "value": "普通交易" + }, + { + "name": "self_selected_settings", + "value": "自选设置" + }, + { + "name": "stock_pk", + "value": "股票PK" + }, + { + "name": "more", + "value": "更多" + }, + { + "name": "go_trade", + "value": "去交易" + }, + { + "name": "transaction_details", + "value": "成交明细" + }, + { + "name": "market_conditions", + "value": "千档行情" + }, + { + "name": "information", + "value": "最新资讯" + }, + { + "name": "announcement", + "value": "某某科技:xxxx公告" + }, + { + "name": "closed_day", + "value": "已收盘 10-19 15:03:03" + }, + { + "name": "some_company_technology", + "value": "某某科技(60**19)" + }, + { + "name": "deep", + "value": "深" + }, + { + "name": "confirm_purchase", + "value": "确认买入" + }, + { + "name": "order_quantity", + "value": "委托数量" + }, + { + "name": "commissioned_price", + "value": "委托价格" + }, + { + "name": "shareholder_account", + "value": "股东账户:500****5" + }, + { + "name": "buy", + "value": "买入" + }, + { + "name": "Stock_name_code", + "value": "某某科技 3****3" + }, + { + "name": "quantity", + "value": "数量" + }, + { + "name": "price", + "value": "价格" + }, + { + "name": "limit_down", + "value": "跌停 " + }, + { + "name": "raising_limit", + "value": " 涨停 " + }, + { + "name": "already_held", + "value": "已持有" + }, + { + "name": "stock", + "value": "股" + }, + { + "name": "buy_able", + "value": "可买" + }, + { + "name": "stock_name", + "value": "股票名称" + }, + { + "name": "stock_number", + "value": "股票编号" + }, + { + "name": "latest_price", + "value": "最新价" + }, + { + "name": "highs_and_lows", + "value": "涨跌" + }, + { + "name": "price_limit", + "value": "涨跌幅" + }, + { + "name": "gross", + "value": "总量" + }, + { + "name": "impressions", + "value": "现量" + }, + { + "name": "volume_transaction", + "value": "成交额" + }, + { + "name": "amplitude", + "value": "振幅" + }, + { + "name": "change_hands", + "value": "换手" + }, + { + "name": "PEG", + "value": "市盈率" + }, + { + "name": "PB", + "value": "市净率" + }, + { + "name": "somebody_technology", + "value": "某某科技" + }, + { + "name": "certain_estate_company", + "value": "某某地产" + }, + { + "name": "certain_pharmaceutical_company", + "value": "某某药业" + }, + { + "name": "billion", + "value": "亿" + }, + { + "name": "growth_enterprise_market", + "value": "创" + }, + { + "name": "securities_margin_trading", + "value": "融" + }, + { + "name": "certain_index", + "value": "某某指数" + }, + { + "name": "deep_number", + "value": "深某某数" + }, + { + "name": "science_technology", + "value": "科创某某" + }, + { + "name": "self_select_stock", + "value": "自选股" + }, + { + "name": "all", + "value": "全部" + }, + { + "name": "add_custom_options", + "value": "添加自选" + }, + { + "name": "optional", + "value": "自选" + }, + { + "name": "market", + "value": "行情" + }, + { + "name": "stock_company", + "value": "券某某股" + }, + { + "name": "stock_text_start", + "value": "本期这些股" + }, + { + "name": "stock_text_end", + "value": "票最被看好" + }, + { + "name": "stock_names", + "value": "股票名称" + }, + { + "name": "home_page", + "value": "首页" + }, + { + "name": "time_share", + "value": "分时" + }, + { + "name": "five_days", + "value": "五日" + }, + { + "name": "daily_k", + "value": "日K" + }, + { + "name": "week_k", + "value": "周K" + }, + { + "name": "month_k", + "value": "月K" + }, + { + "name": "season_k", + "value": "季K" + }, + { + "name": "half_year_k", + "value": "半年K" + }, + { + "name": "year_k", + "value": "年K" + }, + { + "name": "discussion", + "value": "讨论" + }, + { + "name": "must_read", + "value": "必读" + }, + { + "name": "capital", + "value": "资金" + }, + { + "name": "datum", + "value": "资料" + }, + { + "name": "announcements", + "value": "公告" + }, + { + "name": "finance", + "value": "财务" + }, + { + "name": "research_report", + "value": "研报" + }, + { + "name": "related_fund", + "value": "关联基金" + }, + { + "name": "now_begins", + "value": "今开" + }, + { + "name": "yesterday_close", + "value": "昨收" + }, + { + "name": "turnover_rate", + "value": "换手率" + }, + { + "name": "tallest", + "value": "最高" + }, + { + "name": "lowest", + "value": "最低" + }, + { + "name": "turnover", + "value": "成交量" + }, + { + "name": "total_value", + "value": "总市值" + }, + { + "name": "text_hands", + "value": "4570手" + }, + { + "name": "text_billion", + "value": "26.10亿" + }, + { + "name": "turnover_value", + "value": "910.5万" + }, + { + "name": "sell", + "value": "卖" + }, + { + "name": "text_buy", + "value": "买" + } + ] +} \ No newline at end of file diff --git a/hvigor/hvigor-config.json5 b/hvigor/hvigor-config.json5 index 8b8ff50618d906cdaffd93cf2eb4e3310114ec84..7a7ab8914d8db6ab89758e185df5855dffe88d04 100644 --- a/hvigor/hvigor-config.json5 +++ b/hvigor/hvigor-config.json5 @@ -3,11 +3,12 @@ "dependencies": { }, "execution": { - // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | "ultrafine" | false ]. Default: "normal" */ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + // "optimizationStrategy": "memory" /* Define the optimization strategy. Value: [ "memory" | "performance" ]. Default: "memory" */ }, "logging": { // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ diff --git a/hvigorfile.ts b/hvigorfile.ts index f3cb9f1a87a81687554a76283af8df27d8bda775..47113e2e36ecefde41c136272a0bd6ff745cffe4 100644 --- a/hvigorfile.ts +++ b/hvigorfile.ts @@ -1,6 +1,6 @@ import { appTasks } from '@ohos/hvigor-ohos-plugin'; export default { - system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ - plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ -} + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/entry/build-profile.json5 b/products/phone/build-profile.json5 similarity index 30% rename from entry/build-profile.json5 rename to products/phone/build-profile.json5 index 0311b505dbf43f0d22662c8d783c5f4464d15b15..5d1ea7f2ee24f6505f33debc2992fdf1f6794095 100644 --- a/entry/build-profile.json5 +++ b/products/phone/build-profile.json5 @@ -1,22 +1,12 @@ { "apiType": "stageMode", "buildOption": { - }, - "buildOptionSet": [ - { - "name": "release", - "arkOptions": { - "obfuscation": { - "ruleOptions": { - "enable": false, - "files": [ - "./obfuscation-rules.txt" - ] - } - } + "resOptions": { + "copyCodeResource": { + "enable": false } - }, - ], + } + }, "targets": [ { "name": "default" diff --git a/entry/hvigorfile.ts b/products/phone/hvigorfile.ts similarity index 30% rename from entry/hvigorfile.ts rename to products/phone/hvigorfile.ts index c6edcd90486dd5a853cf7d34c8647f08414ca7a3..b0e3a1ab98a91bc918d6404b2413111a5011f14a 100644 --- a/entry/hvigorfile.ts +++ b/products/phone/hvigorfile.ts @@ -1,6 +1,6 @@ import { hapTasks } from '@ohos/hvigor-ohos-plugin'; export default { - system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ - plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ -} + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/entry/obfuscation-rules.txt b/products/phone/obfuscation-rules.txt similarity index 100% rename from entry/obfuscation-rules.txt rename to products/phone/obfuscation-rules.txt diff --git a/products/phone/oh-package.json5 b/products/phone/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9cda0103d6c9d148a9cd2c537508e4aacce342d3 --- /dev/null +++ b/products/phone/oh-package.json5 @@ -0,0 +1,14 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "phone", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dynamicDependencies": {}, + "dependencies": { + "@ohos/commons": "file:../../commons/base", + "@ohos/home": "file:../../features/home" + } +} \ No newline at end of file diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/products/phone/src/main/ets/entryability/EntryAbility.ets similarity index 80% rename from entry/src/main/ets/entryability/EntryAbility.ets rename to products/phone/src/main/ets/entryability/EntryAbility.ets index bf22b541edd334490447076692e6b08b1edb39cd..1b6ede04d92cee75905480397f34cfe4cb174eb4 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/products/phone/src/main/ets/entryability/EntryAbility.ets @@ -17,21 +17,29 @@ import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; import { resourceManager } from '@kit.LocalizationKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { window } from '@kit.ArkUI'; -import Logger from '../utils/Logger'; +import Logger from '@ohos/commons/src/main/ets/utils/Logger'; export default class EntryAbility extends UIAbility { + private windowObj?: window.Window; + private windowStage?: window.WindowStage; private uiContext?: UIContext; private onWindowSizeChange: (windowSize: window.Size) => void = () => { let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint(); AppStorage.setOrCreate('currentWidthBreakpoint', widthBp); let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint(); AppStorage.setOrCreate('currentHeightBreakpoint', heightBp); + // Application adaptation for horizontal and vertical screen switching. + this.windowObj?.setPreferredOrientation(window.Orientation.FOLLOW_DESKTOP).catch((err: BusinessError) => { + Logger.error('EntryAbility', '%{public}s', `setPreferredOrientation failed, code : ${err.code}, message : ${err.message}`); + }); + this.immersionFuc(this.windowStage!); }; private windowStatusChange: (WindowStatusType: window.WindowStatusType) => void = (WindowStatusType: window.WindowStatusType) => { - if (WindowStatusType === 4 || WindowStatusType === 5) { + if (WindowStatusType === window.WindowStatusType.FLOATING || + WindowStatusType === window.WindowStatusType.SPLIT_SCREEN) { AppStorage.setOrCreate('isSplitScreen', true); - } else if (WindowStatusType === 1) { + } else if (WindowStatusType === window.WindowStatusType.FULL_SCREEN) { AppStorage.setOrCreate('isSplitScreen', false); } else { Logger.info('Succeeded in enabling the listener for window status changes. Data: ' + WindowStatusType); @@ -56,6 +64,7 @@ export default class EntryAbility extends UIAbility { // Main window is created, set main page for this ability Logger.info('EntryAbility', '%{public}s', 'Ability onWindowStageCreate'); let context = this.context; + this.windowStage = windowStage; let resourceManager: resourceManager.ResourceManager = context.resourceManager; AppStorage.setOrCreate('resourceManager', resourceManager); windowStage.loadContent('pages/Index', (err, data) => { @@ -65,7 +74,6 @@ export default class EntryAbility extends UIAbility { } Logger.info('EntryAbility', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); - // Immersive Adaptation this.immersionFuc(windowStage); @@ -84,6 +92,7 @@ export default class EntryAbility extends UIAbility { } windowStage.getMainWindow().then((data: window.Window) => { try { + this.windowObj = data; this.uiContext = data.getUIContext(); let widthBp: WidthBreakpoint = this.uiContext.getWindowWidthBreakpoint(); let heightBp: HeightBreakpoint = this.uiContext.getWindowHeightBreakpoint(); @@ -96,6 +105,11 @@ export default class EntryAbility extends UIAbility { }).catch((err: BusinessError) => { Logger.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`); }); + + // Application adaptation for horizontal and vertical screen switching. + this.windowObj?.setPreferredOrientation(window.Orientation.FOLLOW_DESKTOP).catch((err: BusinessError) => { + Logger.error('EntryAbility', '%{public}s', `setPreferredOrientation failed, code : ${err.code}, message : ${err.message}`); + }); }); } @@ -120,7 +134,9 @@ export default class EntryAbility extends UIAbility { immersionFuc(windowStage: window.WindowStage): void { try { let windowClass: window.Window = windowStage.getMainWindowSync(); - windowClass.setWindowLayoutFullScreen(true); + windowClass.setWindowLayoutFullScreen(true).catch((err: BusinessError) => { + Logger.error(`SetWindowLayoutFullScreen failed. Cause code: ${err.code}, message: ${err.message}`); + }); let navigationBarArea: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); @@ -130,7 +146,7 @@ export default class EntryAbility extends UIAbility { AppStorage.setOrCreate('windowClass', windowClass); } catch (error) { let err = error as BusinessError; - Logger.error('EntryAbility', `immersionFuc failed, error code=${err.code}, message=${err.message}`); + Logger.error('EntryAbility', `immersionFuc failed, error code: ${err.code}, message: ${err.message}`); } } } \ No newline at end of file diff --git a/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/products/phone/src/main/ets/entrybackupability/EntryBackupAbility.ets similarity index 94% rename from entry/src/main/ets/entrybackupability/EntryBackupAbility.ets rename to products/phone/src/main/ets/entrybackupability/EntryBackupAbility.ets index e01665b06fa225db979c544b8caffb495d99a2eb..8b78eebd097e5b83927e15da00ce598332200c2d 100644 --- a/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +++ b/products/phone/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -14,7 +14,7 @@ */ import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; -import Logger from '../utils/Logger'; +import Logger from '@ohos/commons/src/main/ets/utils/Logger'; export default class EntryBackupAbility extends BackupExtensionAbility { async onBackup() { diff --git a/entry/src/main/ets/pages/StockDetailsPage.ets b/products/phone/src/main/ets/pages/Index.ets similarity index 84% rename from entry/src/main/ets/pages/StockDetailsPage.ets rename to products/phone/src/main/ets/pages/Index.ets index eb5f52d628ccdbaed595793eda72856a924a375d..584293bdba3e4d5cde5458430eede8595e6f718c 100644 --- a/entry/src/main/ets/pages/StockDetailsPage.ets +++ b/products/phone/src/main/ets/pages/Index.ets @@ -13,11 +13,14 @@ * limitations under the License. */ -import { StockDetailsView } from '../views/StockDetailsView'; +import { Home } from '@ohos/home'; +@Entry @Component -export struct StockDetailsPage { +struct Index { build() { - StockDetailsView() + Column() { + Home() + } } } \ No newline at end of file diff --git a/products/phone/src/main/ets/splitScreenAbility/SplitScreenAbility.ets b/products/phone/src/main/ets/splitScreenAbility/SplitScreenAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..2223c454e0402f79f02cd1bc00952a19823ea9d0 --- /dev/null +++ b/products/phone/src/main/ets/splitScreenAbility/SplitScreenAbility.ets @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit'; +import { resourceManager } from '@kit.LocalizationKit'; +import { BusinessError, emitter } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; +import Logger from '@ohos/commons/src/main/ets/utils/Logger'; + +let eventData: emitter.EventData = { + data: { + 'isStart': 1, + 'id': 1 + } +}; +let innerEvent: emitter.InnerEvent = { + eventId: 1, + priority: emitter.EventPriority.HIGH +}; + +export default class SplitScreenAbility extends UIAbility { + private uiContext?: UIContext; + private onWindowSizeChange: (windowSize: window.Size) => void = () => { + let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint(); + AppStorage.setOrCreate('currentWidthBreakpoint', widthBp); + let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint(); + AppStorage.setOrCreate('currentHeightBreakpoint', heightBp); + }; + private windowStatusChange: (WindowStatusType: window.WindowStatusType) => void = + (WindowStatusType: window.WindowStatusType) => { + if (WindowStatusType === window.WindowStatusType.FLOATING || + WindowStatusType === window.WindowStatusType.SPLIT_SCREEN) { + AppStorage.setOrCreate('isSplitScreen', true); + } else if (WindowStatusType === window.WindowStatusType.FULL_SCREEN) { + AppStorage.setOrCreate('isSplitScreen', false); + } else { + Logger.info('Succeeded in enabling the listener for window status changes. Data: ' + WindowStatusType); + } + }; + + onCreate(): void { + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onCreate'); + AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode); + AppStorage.setOrCreate('isHideSplitScreen', true); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (exception) { + Logger.error(`Failed to setColorMode. Cause code: ${exception.code}, message: ${exception.message}`); + } + emitter.emit(innerEvent, eventData); + } + + onNewWant(): void { + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onCreate'); + AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode); + AppStorage.setOrCreate('isHideSplitScreen', true); + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (exception) { + Logger.error(`Failed to setColorMode. Cause code: ${exception.code}, message: ${exception.message}`); + } + emitter.emit(innerEvent, eventData); + } + + onDestroy(): void { + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onWindowStageCreate'); + let context = this.context; + let resourceManager: resourceManager.ResourceManager = context.resourceManager; + AppStorage.setOrCreate('resourceManager', resourceManager); + let storage: LocalStorage = new LocalStorage(false); + storage.setOrCreate('SplitScreenMode', false); + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Logger.error('SplitScreenAbility', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + Logger.info('SplitScreenAbility', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + + // Immersive Adaptation + this.immersionFuc(windowStage); + + const isWindowAvailable = canIUse('SystemCapability.Window.SessionManager'); + if (isWindowAvailable) { + // Determine the current application window mode. + // 1: Full-screen split-screen mode, 5: Split-screen mode, 4: Panoramic multi-window mode + try { + let windowClass: window.Window = windowStage.getMainWindowSync(); + windowClass.on('windowStatusChange', this.windowStatusChange); + } catch (exception) { + Logger.error(`Failed to unregister callback. Cause code: ${exception.code}, message: ${exception.message}`); + } + } else { + Logger.info('Window not by this device.'); + } + windowStage.getMainWindow().then((data: window.Window) => { + try { + this.uiContext = data.getUIContext(); + let widthBp: WidthBreakpoint = this.uiContext.getWindowWidthBreakpoint(); + let heightBp: HeightBreakpoint = this.uiContext.getWindowHeightBreakpoint(); + AppStorage.setOrCreate('currentWidthBreakpoint', widthBp); + AppStorage.setOrCreate('currentHeightBreakpoint', heightBp); + data.on('windowSizeChange', this.onWindowSizeChange); + } catch (error) { + Logger.error(`GetUIContext failed. Cause code: ${err.code}, message: ${err.message}`); + } + }).catch((err: BusinessError) => { + Logger.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`); + }); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + Logger.info('SplitScreenAbility', '%{public}s', 'Ability onBackground'); + } + + /** + * Page immersion. + */ + immersionFuc(windowStage: window.WindowStage): void { + try { + let windowClass: window.Window = windowStage.getMainWindowSync(); + windowClass.setWindowLayoutFullScreen(true).catch((err: BusinessError) => { + Logger.error(`SetWindowLayoutFullScreen failed. Cause code: ${err.code}, message: ${err.message}`); + }); + let navigationBarArea: window.AvoidArea = + windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + let area: window.AvoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + AppStorage.setOrCreate('naviIndicatorHeight', + windowClass.getUIContext().px2vp(navigationBarArea.bottomRect.height)); + AppStorage.setOrCreate('statusBarHeight', windowClass.getUIContext().px2vp(area.topRect.height)); + AppStorage.setOrCreate('windowClass', windowClass); + } catch (error) { + let err = error as BusinessError; + Logger.error('SplitScreenAbility', `immersionFuc failed, error code=${err.code}, message=${err.message}`); + } + } +} \ No newline at end of file diff --git a/products/phone/src/main/ets/splitScreenBackupAbility/SplitScreenBackupAbility.ets b/products/phone/src/main/ets/splitScreenBackupAbility/SplitScreenBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..c97dcfd87ccb0fd8239ee68ac2ac1b7e0ab25163 --- /dev/null +++ b/products/phone/src/main/ets/splitScreenBackupAbility/SplitScreenBackupAbility.ets @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; +import Logger from '@ohos/commons/src/main/ets/utils/Logger'; + +export default class SplitScreenBackupAbility extends BackupExtensionAbility { + async onBackup() { + Logger.info('SplitScreenBackupAbility', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + Logger.info('SplitScreenBackupAbility', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/entry/src/main/module.json5 b/products/phone/src/main/module.json5 similarity index 50% rename from entry/src/main/module.json5 rename to products/phone/src/main/module.json5 index 71af0484e598176a548d4668f485f055b27ee64f..a05fc168af9d503cc0741a06b3dcca1afeba3ba9 100644 --- a/entry/src/main/module.json5 +++ b/products/phone/src/main/module.json5 @@ -1,12 +1,12 @@ { "module": { - "name": "entry", + "name": "phone", "type": "entry", "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ "phone", - "tablet" + "tablet", ], "deliveryWithInstall": true, "installationFree": false, @@ -21,7 +21,37 @@ "startWindowIcon": "$media:startIcon", "startWindowBackground": "$color:start_window_background", "exported": true, - "supportWindowMode": ["fullscreen", "split", "floating"], + "supportWindowMode": [ + "fullscreen", + "split", + "floating" + ], + "launchType": "multiton", + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + }, + { + "name": "SplitScreenAbility", + "srcEntry": "./ets/splitScreenAbility/SplitScreenAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "supportWindowMode": [ + "fullscreen", + "split", + "floating" + ], "launchType": "multiton", "skills": [ { @@ -46,7 +76,19 @@ "name": "ohos.extension.backup", "resource": "$profile:backup_config" } - ], + ] + }, + { + "name": "SplitScreenBackupAbility", + "srcEntry": "./ets/splitScreenBackupAbility/SplitScreenBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ] } ] } diff --git a/products/phone/src/main/resources/base/element/color.json b/products/phone/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/products/phone/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/products/phone/src/main/resources/base/element/float.json b/products/phone/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/products/phone/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/products/phone/src/main/resources/base/element/string.json b/products/phone/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..448a8c6aea3bbee7ccc7da78dd7b6837e953936d --- /dev/null +++ b/products/phone/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "MultiStockCategoryApp" + } + ] +} \ No newline at end of file diff --git a/products/phone/src/main/resources/base/media/background.png b/products/phone/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/products/phone/src/main/resources/base/media/background.png differ diff --git a/products/phone/src/main/resources/base/media/foreground.png b/products/phone/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/products/phone/src/main/resources/base/media/foreground.png differ diff --git a/products/phone/src/main/resources/base/media/layered_image.json b/products/phone/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/products/phone/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/products/phone/src/main/resources/base/media/startIcon.png b/products/phone/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/products/phone/src/main/resources/base/media/startIcon.png differ diff --git a/products/phone/src/main/resources/base/profile/backup_config.json b/products/phone/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/products/phone/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/entry/src/main/resources/base/profile/main_pages.json b/products/phone/src/main/resources/base/profile/main_pages.json similarity index 100% rename from entry/src/main/resources/base/profile/main_pages.json rename to products/phone/src/main/resources/base/profile/main_pages.json diff --git a/products/phone/src/main/resources/dark/element/color.json b/products/phone/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/products/phone/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/products/phone/src/main/resources/en_US/element/string.json b/products/phone/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..448a8c6aea3bbee7ccc7da78dd7b6837e953936d --- /dev/null +++ b/products/phone/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "MultiStockCategoryApp" + } + ] +} \ No newline at end of file diff --git a/products/phone/src/main/resources/zh_CN/element/string.json b/products/phone/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..2515b42e2bdb272dec0ae8e6a4461f95c652e1c5 --- /dev/null +++ b/products/phone/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "一多股票类应用" + } + ] +} \ No newline at end of file