初步解决自适应问题
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 { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { window } from '@kit.ArkUI';
|
||||
import { AppStorageV2 } from '@kit.ArkUI';
|
||||
import { window,display,AppStorageV2} from '@kit.ArkUI';
|
||||
import { WindowUIContextUtils } from '../common/WindowUtils';
|
||||
import { PixelUtils } from '../common/UIContext';
|
||||
|
||||
const DOMAIN = 0x0000;
|
||||
|
||||
@ -22,13 +23,45 @@ export default class EntryAbility extends UIAbility {
|
||||
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||
// Main window is created, set main page for this ability
|
||||
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
let window = windowStage.getMainWindowSync();
|
||||
// 注册主窗的回调。
|
||||
WindowUIContextUtils.registerWindowCallback(window);
|
||||
windowStage.loadContent('pages/Index', (err) => {
|
||||
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;
|
||||
}
|
||||
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.');
|
||||
});
|
||||
}
|
||||
|
||||
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'){
|
||||
OCCTLoadModel(undefined,undefined)
|
||||
}else if(event?.eEvent=='Execute_CreateSubWindow'){
|
||||
CreateAndShowSubWindow(event.ePage);
|
||||
CreateAndShowSubWindow(event.eName,event.ePage);
|
||||
}else if(event?.eEvent=='Execute_ExitSubWindow'){
|
||||
CloseSubWindow();
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { window } from '@kit.ArkUI';
|
||||
import { window,UIContext} from '@kit.ArkUI';
|
||||
|
||||
let subWindow: window.Window | undefined = undefined;
|
||||
|
||||
export async function CreateAndShowSubWindow(pages:string) {
|
||||
export async function CreateAndShowSubWindow(name:string,pages:string) {
|
||||
try {
|
||||
const windowStage = AppStorage.get('windowStage') as window.WindowStage;
|
||||
if(windowStage==null){
|
||||
@ -11,35 +11,36 @@ export async function CreateAndShowSubWindow(pages:string) {
|
||||
return;
|
||||
}
|
||||
let options: window.SubWindowOptions = {
|
||||
title: '子窗口',
|
||||
title: name,
|
||||
decorEnabled: true,
|
||||
isModal: false,
|
||||
maximizeSupported: false,
|
||||
zLevel:-1,
|
||||
outlineEnabled:true,
|
||||
};
|
||||
|
||||
await windowStage.createSubWindowWithOptions('subWindow', options).then((data) => {
|
||||
subWindow = data;
|
||||
subWindow.setResizeByDragEnabled(true, (err: BusinessError) => {
|
||||
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) => {
|
||||
if (err.code) {
|
||||
console.error("加载页面失败:", err);
|
||||
return;
|
||||
}
|
||||
})
|
||||
// 显示窗口
|
||||
subWindow?.showWindow((err) => {
|
||||
subWindow.showWindow((err) => {
|
||||
if (err.code) {
|
||||
console.error("显示窗口失败:", err);
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to create or show sub window:', (error as BusinessError).message);
|
||||
}
|
||||
|
||||
@ -1,18 +1,29 @@
|
||||
import { Expandable } from '../CustomStyle/Expandable';
|
||||
|
||||
@Entry
|
||||
@ComponentV2
|
||||
struct SWExtrude {
|
||||
|
||||
// 控制内容区域显示与隐藏的状态
|
||||
@Provider('isSubExpanded') isExpanded:boolean=true;
|
||||
build() {
|
||||
Column() {
|
||||
Row({ space: 20 }) {
|
||||
Blank().width(8);
|
||||
Column({ space: 5 }) {
|
||||
Column(){
|
||||
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)
|
||||
.height(56)
|
||||
.width('100%')
|
||||
.padding({ left: 10 })
|
||||
.backgroundColor('#f2f2f2');
|
||||
}.width('100%').height('100%');
|
||||
}.justifyContent(FlexAlign.Start)
|
||||
}
|
||||
}.width('100%') // 容器宽度
|
||||
.padding(15) // 内边距
|
||||
.backgroundColor('#ffffff') // 背景色
|
||||
.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