初步解决自适应问题
This commit is contained in:
parent
6e73610503
commit
68e72767dd
31
entry/src/main/ets/common/ContextUtils.ets
Normal file
31
entry/src/main/ets/common/ContextUtils.ets
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// [Start Common_ContextUtils]
|
||||||
|
export class ContextUtils {
|
||||||
|
public static context: Context | undefined;
|
||||||
|
|
||||||
|
static setContext(context: Context): void {
|
||||||
|
ContextUtils.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getContext(uiContext?: UIContext): Context | undefined {
|
||||||
|
if (uiContext) {
|
||||||
|
return uiContext.getHostContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ContextUtils.context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// [End Common_ContextUtils]
|
||||||
57
entry/src/main/ets/common/UIContext.ets
Normal file
57
entry/src/main/ets/common/UIContext.ets
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// [Start Common_PixelUtils]
|
||||||
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||||
|
import { display } from '@kit.ArkUI';
|
||||||
|
|
||||||
|
const DOMAIN = 0x0000;
|
||||||
|
|
||||||
|
export class PixelUtils {
|
||||||
|
public static uiContext: UIContext | undefined;
|
||||||
|
|
||||||
|
static setUIContext(uiContext: UIContext): void {
|
||||||
|
PixelUtils.uiContext = uiContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vp2px(vpValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtils.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
let displayClass = display.getDefaultDisplaySync();
|
||||||
|
let density = displayClass.densityPixels;
|
||||||
|
return vpValue * density;
|
||||||
|
}
|
||||||
|
return _uiContext.vp2px(vpValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fp2px(fpValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtils.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return _uiContext.fp2px(fpValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
lpx2px(lpxValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtils.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return _uiContext.lpx2px(lpxValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [End Common_PixelUtils]
|
||||||
60
entry/src/main/ets/common/Utils.ets
Normal file
60
entry/src/main/ets/common/Utils.ets
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// [Start Common_Utils]
|
||||||
|
// common/Utils.ets
|
||||||
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||||
|
|
||||||
|
const DOMAIN = 0x0000;
|
||||||
|
|
||||||
|
export class PixelUtil {
|
||||||
|
static uiContext: UIContext | undefined;
|
||||||
|
|
||||||
|
static setUIContext(uiContext: UIContext): void {
|
||||||
|
PixelUtil.uiContext = uiContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static removeUIContext(): void {
|
||||||
|
PixelUtil.uiContext = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vp2px(vpValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtil.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return _uiContext.vp2px(vpValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fp2px(fpValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtil.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return _uiContext.fp2px(fpValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
lpx2px(lpxValue: number, uiContext?: UIContext): number | undefined {
|
||||||
|
let _uiContext = uiContext ?? PixelUtil.uiContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return _uiContext.lpx2px(lpxValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [End Common_Utils]
|
||||||
62
entry/src/main/ets/common/WindowUtils.ets
Normal file
62
entry/src/main/ets/common/WindowUtils.ets
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// [Start Common_WindowUtils]
|
||||||
|
// common/WindowUtils.ets
|
||||||
|
import { display, window } from '@kit.ArkUI';
|
||||||
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||||
|
|
||||||
|
const DOMAIN = 0x0000;
|
||||||
|
|
||||||
|
export class WindowUIContextUtils {
|
||||||
|
public static activeUIContext: UIContext | undefined;
|
||||||
|
|
||||||
|
static registerWindowCallback(windowClass: window.Window): void {
|
||||||
|
try {
|
||||||
|
windowClass.on('windowEvent', (event: window.WindowEventType) => {
|
||||||
|
if (event === window.WindowEventType.WINDOW_ACTIVE) {
|
||||||
|
try {
|
||||||
|
let uiContext = windowClass.getUIContext();
|
||||||
|
WindowUIContextUtils.activeUIContext = uiContext;
|
||||||
|
} catch (exception) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext, ${exception}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (exception) {
|
||||||
|
console.error(`Failed to unregister callback. Cause: ${exception}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unregisterWindowCallback(windowClass: window.Window): void {
|
||||||
|
windowClass.off('windowEvent');
|
||||||
|
}
|
||||||
|
|
||||||
|
static setActiveUIContext(uiContext: UIContext): void {
|
||||||
|
WindowUIContextUtils.activeUIContext = uiContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vp2px(vpValue: number, uiContext?: UIContext): number {
|
||||||
|
let _uiContext = uiContext ?? WindowUIContextUtils.activeUIContext;
|
||||||
|
if (!_uiContext || !_uiContext.isAvailable()) {
|
||||||
|
let displayClass = display.getDefaultDisplaySync();
|
||||||
|
let density = displayClass.densityPixels;
|
||||||
|
return vpValue * density;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _uiContext.vp2px(vpValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [End Common_WindowUtils]
|
||||||
@ -1,7 +1,8 @@
|
|||||||
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
|
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
|
||||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||||
import { window } from '@kit.ArkUI';
|
import { window,display,AppStorageV2} from '@kit.ArkUI';
|
||||||
import { AppStorageV2 } from '@kit.ArkUI';
|
import { WindowUIContextUtils } from '../common/WindowUtils';
|
||||||
|
import { PixelUtils } from '../common/UIContext';
|
||||||
|
|
||||||
const DOMAIN = 0x0000;
|
const DOMAIN = 0x0000;
|
||||||
|
|
||||||
@ -22,13 +23,45 @@ export default class EntryAbility extends UIAbility {
|
|||||||
onWindowStageCreate(windowStage: window.WindowStage): void {
|
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||||
// Main window is created, set main page for this ability
|
// Main window is created, set main page for this ability
|
||||||
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||||
|
let window = windowStage.getMainWindowSync();
|
||||||
|
// 注册主窗的回调。
|
||||||
|
WindowUIContextUtils.registerWindowCallback(window);
|
||||||
windowStage.loadContent('pages/Index', (err) => {
|
windowStage.loadContent('pages/Index', (err) => {
|
||||||
if (err.code) {
|
if (err.code) {
|
||||||
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
|
hilog.error(DOMAIN, 'Tag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AppStorage.setOrCreate('windowStage', windowStage);
|
AppStorage.setOrCreate('windowStage', windowStage);
|
||||||
|
let uiContext = window.getUIContext();
|
||||||
|
PixelUtils.setUIContext(uiContext);
|
||||||
|
// 主窗获焦可能早于loadContent完成,需要在成功后设置保证有效。
|
||||||
|
WindowUIContextUtils.setActiveUIContext(uiContext)
|
||||||
|
if (!uiContext) {
|
||||||
|
hilog.error(DOMAIN, 'testTag', `Can't get UIContext`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let screenWidth:number=display.getDefaultDisplaySync().width;
|
||||||
|
let screenHeight:number=display.getDefaultDisplaySync().height;
|
||||||
|
//定义新的宽度和高度(单位:虚拟像素)
|
||||||
|
const newWidth: number = screenWidth-uiContext.px2vp(200);
|
||||||
|
const newHeight: number = screenHeight-uiContext.px2vp(400);
|
||||||
|
|
||||||
|
//基于物理分辨率在长和高上分别缩小200vp
|
||||||
|
windowStage.getMainWindow((err, mainWindow) => {
|
||||||
|
if (err.code) {
|
||||||
|
console.error(`Failed to obtain the main window. Code: ${err.code}, message: ${err.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mainWindow.moveWindowTo(uiContext.px2vp(100),uiContext.px2vp(100))
|
||||||
|
//调用resize方法修改窗口大小
|
||||||
|
mainWindow.resize(newWidth, newHeight, (err) => {
|
||||||
|
if (err.code) {
|
||||||
|
console.error(`Failed to resize the window. Code: ${err.code}, message: ${err.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.info(`Succeeded in resizing the window to ${newWidth}x${newHeight}.`);
|
||||||
|
});
|
||||||
|
});
|
||||||
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
|
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
27
entry/src/main/ets/pages/CustomStyle/Expandable.ets
Normal file
27
entry/src/main/ets/pages/CustomStyle/Expandable.ets
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//一个复合式折叠组件
|
||||||
|
@ComponentV2
|
||||||
|
export struct Expandable {
|
||||||
|
// 通过属性传入的标题和内容
|
||||||
|
@Param title: string|undefined=undefined;
|
||||||
|
// 控制内容区域显示与隐藏的状态
|
||||||
|
@Consumer('isSubExpanded') isSubExpanded: boolean=true;
|
||||||
|
build(){
|
||||||
|
// 标题行
|
||||||
|
Row({ space: 5 }) {
|
||||||
|
// 切换按钮,显示向上或向下箭头
|
||||||
|
Button(this.isSubExpanded ? '▲' : '▼')
|
||||||
|
.type(ButtonType.Normal)
|
||||||
|
.fontSize(14)
|
||||||
|
.onClick(() => {
|
||||||
|
// 点击按钮时,切换 isSubExpanded 状态
|
||||||
|
this.isSubExpanded = !this.isSubExpanded;
|
||||||
|
})
|
||||||
|
Text(this.title)
|
||||||
|
.fontSize(18)
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
.alignSelf(ItemAlign.Center)
|
||||||
|
}.width('100%')
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ export function ExecuteCommand(event:TitleButton){
|
|||||||
if(event?.eEvent=='Execute_LoadModel'){
|
if(event?.eEvent=='Execute_LoadModel'){
|
||||||
OCCTLoadModel(undefined,undefined)
|
OCCTLoadModel(undefined,undefined)
|
||||||
}else if(event?.eEvent=='Execute_CreateSubWindow'){
|
}else if(event?.eEvent=='Execute_CreateSubWindow'){
|
||||||
CreateAndShowSubWindow(event.ePage);
|
CreateAndShowSubWindow(event.eName,event.ePage);
|
||||||
}else if(event?.eEvent=='Execute_ExitSubWindow'){
|
}else if(event?.eEvent=='Execute_ExitSubWindow'){
|
||||||
CloseSubWindow();
|
CloseSubWindow();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { BusinessError } from '@kit.BasicServicesKit';
|
import { BusinessError } from '@kit.BasicServicesKit';
|
||||||
import { window } from '@kit.ArkUI';
|
import { window,UIContext} from '@kit.ArkUI';
|
||||||
|
|
||||||
let subWindow: window.Window | undefined = undefined;
|
let subWindow: window.Window | undefined = undefined;
|
||||||
|
|
||||||
export async function CreateAndShowSubWindow(pages:string) {
|
export async function CreateAndShowSubWindow(name:string,pages:string) {
|
||||||
try {
|
try {
|
||||||
const windowStage = AppStorage.get('windowStage') as window.WindowStage;
|
const windowStage = AppStorage.get('windowStage') as window.WindowStage;
|
||||||
if(windowStage==null){
|
if(windowStage==null){
|
||||||
@ -11,35 +11,36 @@ export async function CreateAndShowSubWindow(pages:string) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let options: window.SubWindowOptions = {
|
let options: window.SubWindowOptions = {
|
||||||
title: '子窗口',
|
title: name,
|
||||||
decorEnabled: true,
|
decorEnabled: true,
|
||||||
isModal: false,
|
isModal: false,
|
||||||
maximizeSupported: false,
|
maximizeSupported: false,
|
||||||
zLevel:-1,
|
zLevel:-1,
|
||||||
outlineEnabled:true,
|
outlineEnabled:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
await windowStage.createSubWindowWithOptions('subWindow', options).then((data) => {
|
await windowStage.createSubWindowWithOptions('subWindow', options).then((data) => {
|
||||||
subWindow = data;
|
subWindow = data;
|
||||||
subWindow.setResizeByDragEnabled(true, (err: BusinessError) => {
|
subWindow.setResizeByDragEnabled(true, (err: BusinessError) => {
|
||||||
console.log("设置拖拽缩放", `报错信息:${err.code}, ${err.message}`)
|
console.log("设置拖拽缩放", `报错信息:${err.code}, ${err.message}`)
|
||||||
})
|
})
|
||||||
//子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
|
//子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
|
||||||
subWindow.moveWindowTo(150, 300)
|
subWindow.moveWindowTo(150, 15)
|
||||||
//子窗口重置大小
|
//子窗口重置大小
|
||||||
subWindow.resize(500, 900);
|
subWindow.resize(800, 1200);
|
||||||
subWindow.setUIContent(pages, (err: BusinessError) => {
|
subWindow.setUIContent(pages, (err: BusinessError) => {
|
||||||
if (err.code) {
|
if (err.code) {
|
||||||
console.error("加载页面失败:", err);
|
console.error("加载页面失败:", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
})
|
||||||
// 显示窗口
|
// 显示窗口
|
||||||
subWindow?.showWindow((err) => {
|
subWindow.showWindow((err) => {
|
||||||
if (err.code) {
|
if (err.code) {
|
||||||
console.error("显示窗口失败:", err);
|
console.error("显示窗口失败:", err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create or show sub window:', (error as BusinessError).message);
|
console.error('Failed to create or show sub window:', (error as BusinessError).message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,29 @@
|
|||||||
|
import { Expandable } from '../CustomStyle/Expandable';
|
||||||
|
|
||||||
@Entry
|
@Entry
|
||||||
@ComponentV2
|
@ComponentV2
|
||||||
struct SWExtrude {
|
struct SWExtrude {
|
||||||
|
// 控制内容区域显示与隐藏的状态
|
||||||
|
@Provider('isSubExpanded') isExpanded:boolean=true;
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column({ space: 5 }) {
|
||||||
Row({ space: 20 }) {
|
Column(){
|
||||||
Blank().width(8);
|
Expandable({title:"拉伸"});
|
||||||
|
Row(){
|
||||||
|
// 内容区域,使用条件渲染来控制显示与隐藏
|
||||||
|
if (this.isExpanded) {
|
||||||
|
Text('*选择曲线(0)').width(px2vp(35)).height(px2vp(35))
|
||||||
|
Blank().width('30%')
|
||||||
|
Button('绘制曲线').width(px2vp(35)).height(px2vp(35))
|
||||||
|
Button('选择曲线').width(px2vp(35)).height(px2vp(35))
|
||||||
}
|
}
|
||||||
.justifyContent(FlexAlign.SpaceBetween)
|
}.justifyContent(FlexAlign.Start)
|
||||||
.height(56)
|
}
|
||||||
.width('100%')
|
}.width('100%') // 容器宽度
|
||||||
.padding({ left: 10 })
|
.padding(15) // 内边距
|
||||||
.backgroundColor('#f2f2f2');
|
.backgroundColor('#ffffff') // 背景色
|
||||||
}.width('100%').height('100%');
|
.borderRadius(8) // 边框圆角
|
||||||
|
.shadow({ radius: 4, color: '#1f000000', offsetX: 2, offsetY: 2 }) // 添加阴影
|
||||||
|
.margin({ top: 5, left: 5, bottom: 5, right: 5 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user