【HarmonyOS NEXT】自定义的弹窗是否有最佳实践方案

 【关键字】

自定义弹窗 / promptAction.openCustomDialog / CustomDialogController

【问题描述】

目前尝试了两种自定义弹窗方案都有问题:

1、promptAction.openCustomDialog

无法灵活自定义弹窗,宽度无法自定义,弹窗的圆角无法自定义。模态情况下(isModal为true),点击弹窗外部,弹窗会自动关闭,但是需要实现的效果是点击弹窗外部不自动关闭。非模态情况下(isModal为false),点击弹窗外空白区域不会自动关闭,但点击有点击事件的按钮时还会触发并且弹窗也会消失。

2、CustomDialogController

这种方式使用上不方便,无法进行工具类封装,需要在调用的地方都实现一次。

【解决方案】

openCustomDialog宽度自定义,弹窗的圆角自定义,点击弹窗外空白区域,不会自动关闭等功能当前还不支持,正在开发中。建议先通过子窗口规避。

子窗口实现demo如下:

// subWindow.ets
import window from '@ohos.window';

@Entry
@Component
export struct Index2 {

build() {
Row() {
Column() {
Button("close")
.width(155)
.height(55)
.margin({ left: 20 })
.backgroundColor(0xF55A42)
.onClick(() => {
this.destroySubWindow();
})
}
.borderRadius({
topLeft:20,
topRight:20,
bottomLeft:20,
bottomRight:20
})
.margin({ bottom: 10})
.backgroundColor('#FFFFFF')
.width('90%')
.height(100)
}
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Bottom)
.width('100%')
.height('100%')
}

private destroySubWindow() {
window.findWindow("mySubWindow").destroyWindow((err) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to destroy the window. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in destroying the window.');
});
}
}

调用实现:

// xxx.ets
import window from '@ohos.window';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
interface Data {
subWindowStage: window.WindowStage | null
}
@Entry
@Component
struct Index {
private subWindow: window.Window | null = null;
private windowStage1: window.WindowStage | null = null
private context: common.UIAbilityContext | null = null;
private windowHeight:number = 0;
private windowWidth:number = 0;

async aboutToAppear() {
console.log("@nlh@ aboutToAppear before createWindow");
this.context = getContext(this) as common.UIAbilityContext;
let data : Data = {
subWindowStage: null
};
this.context.eventHub.emit("createWindow", data);
this.windowStage1 = data.subWindowStage;
if(this.windowStage1) {
// 获取当前窗口大小,子窗口大小与当前窗口一致
await this.windowStage1.getMainWindow().then((window) => {
this.windowHeight = window.getWindowProperties().windowRect.height
this.windowWidth = window.getWindowProperties().windowRect.width
})
}
console.log("@nlh@ aboutToAppear end createWindow");
}

private showSubWindow() {
if (this.subWindow) {
this.subWindow.showWindow((err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
console.error('@nlh@ Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('@nlh@ Succeeded in showing the window.');
});
} else {
console.info('@nlh@ showSubWindow subWindow not created.');
}
}
private loadContent() {
if (this.subWindow) {
this.subWindow.setUIContent("pages/subWindow", (err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
if (this.subWindow){
//设置子窗口背景颜色,模拟弹窗蒙层效果
this.subWindow.setWindowBackgroundColor('#22222222')
}
});
} else {
console.info('@nlh@ loadContent subWindow not created.');
}
}

private createSubWindow() {
try {
if (!this.windowStage1) {
console.error("@nlh@ this.windowStage1 is null");
return;
}
this.windowStage1.createSubWindow('mySubWindow', (err: BusinessError, data) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
return;
}
this.subWindow = (data as window.Window);
if (!this.subWindow) {
console.info('Failed to load the content. Cause: windowClass is null');
} else {
this.subWindow.resize(this.windowWidth, this.windowHeight);
this.subWindow.moveWindowTo(0, 0);
this.subWindow.setWindowTouchable(true);
this.loadContent();
this.showSubWindow();
}
});
} catch (exception) {
console.error('@nlh@ Failed to create the window. Cause: ' + JSON.stringify(exception));
}
}

build() {
Row() {
Column() {
Text('Circle button').fontSize(30).fontColor(0xff0000)
Button("open")
.width(155)
.height(55)
.margin({ left: 20 })
.backgroundColor(0xF55A42)
.onClick(() => {
this.createSubWindow();
})
}.width('100%')
}.height('100%')
}
}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值