关于弹窗,根据用户交互操作场景,可分为模态弹窗和非模态弹窗两种类型,其区别在于用户是否必须对其做出响应。
由于CustomDialog在使用上存在较多限制,不支持动态创建和动态刷新,在相对较复杂的应用场景中推荐使用UIContext中获取到的PromptAction对象提供的openCustomDialog接口来实现自定义弹出框。以下是基于PromptAction封装的自定义弹窗实现横竖屏居中显示不遮挡的示例,具体实现步骤如下:
private contentNode: ComponentContent<Object> = new ComponentContent(this.ctx, wrapBuilder(buildText));
PromptActionClass.ctx.getPromptAction()
.openCustomDialog(PromptActionClass.contentNode, PromptActionClass.options)
.then(() => {
console.info('OpenCustomDialog complete.');
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`);
});
PromptActionClass.ctx.getPromptAction()
.closeCustomDialog(PromptActionClass.contentNode)
.then(() => {
console.info('CloseCustomDialog complete.');
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`CloseCustomDialog args error code is ${code}, message is ${message}`);
});
aboutToAppear(): void {
PromptActionClass.setContext(this.ctx);
PromptActionClass.setContentNode(this.contentNode);
PromptActionClass.setOptions({ alignment: DialogAlignment.Center });
}
@Builder
function buildText() {
Column() {
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Text('账号登录').fontSize(24).fontWeight(FontWeight.Bold);
Image($r('app.media.close'))
.width(32)
.height(32)
.onClick(() => {
PromptActionClass.closeDialog();
});
}.padding({ bottom: 24 });
Column() {
TextInput({ placeholder: '邮箱' })
.width('100%')
.showUnderline(true);
TextInput({ placeholder: '验证码' })
.width('100%')
.showUnderline(true);
Row() {
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
.select(false)
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
console.info('Checkbox2 change is' + value);
});
Text('我已阅读并同意《隐私政策》');
}.padding({ top: 12, bottom: 12 });
};
Button('登录')
.width('100%')
.onClick(() => {
PromptActionClass.closeDialog();
});
Column() {
Text('其他账号登录').padding({ bottom: 12 });
Row() {
Image($r('app.media.huawei')).width(32).height(32).margin({ right: 12 });
};
}
.padding({ top: 24 });
}.backgroundColor('#FFF0F0F0')
.padding(24)
.width(480)
.border({ radius: '10%' });
}
完整示例如下:
import { BusinessError } from '@kit.BasicServicesKit';
import { ComponentContent, promptAction, UIContext } from '@kit.ArkUI';
export class PromptActionClass {
static ctx: UIContext;
static contentNode: ComponentContent<Object>;
static options: promptAction.BaseDialogOptions;
static setContext(context: UIContext) {
PromptActionClass.ctx = context;
}
static setContentNode(node: ComponentContent<Object>) {
PromptActionClass.contentNode = node;
}
static setOptions(options: promptAction.BaseDialogOptions) {
PromptActionClass.options = options;
}
static openDialog() {
if (PromptActionClass.contentNode !== null) {
PromptActionClass.ctx.getPromptAction()
.openCustomDialog(PromptActionClass.contentNode, PromptActionClass.options)
.then(() => {
console.info('OpenCustomDialog complete.');
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`);
});
}
}
static closeDialog() {
if (PromptActionClass.contentNode !== null) {
PromptActionClass.ctx.getPromptAction()
.closeCustomDialog(PromptActionClass.contentNode)
.then(() => {
console.info('CloseCustomDialog complete.');
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`CloseCustomDialog args error code is ${code}, message is ${message}`);
});
}
}
static updateDialog(options: promptAction.BaseDialogOptions) {
if (PromptActionClass.contentNode !== null) {
PromptActionClass.ctx.getPromptAction()
.updateCustomDialog(PromptActionClass.contentNode, options)
.then(() => {
console.info('UpdateCustomDialog complete.');
})
.catch((error: BusinessError) => {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`UpdateCustomDialog args error code is ${code}, message is ${message}`);
});
}
}
} // Index.ets
import { ComponentContent } from '@kit.ArkUI';
import { PromptActionClass } from './PromptActionView';
@Builder
function buildText() {
Column() {
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Text('账号登录').fontSize(24).fontWeight(FontWeight.Bold);
Image($r('app.media.close'))
.width(32)
.height(32)
.onClick(() => {
PromptActionClass.closeDialog();
});
}.padding({ bottom: 24 });
Column() {
TextInput({ placeholder: '邮箱' })
.width('100%')
.showUnderline(true);
TextInput({ placeholder: '验证码' })
.width('100%')
.showUnderline(true);
Row() {
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
.select(false)
.selectedColor(0x39a2db)
.shape(CheckBoxShape.ROUNDED_SQUARE)
.onChange((value: boolean) => {
console.info('Checkbox2 change is' + value);
});
Text('我已阅读并同意《隐私政策》');
}.padding({ top: 12, bottom: 12 });
};
Button('登录')
.width('100%')
.onClick(() => {
PromptActionClass.closeDialog();
});
Column() {
Text('其他账号登录').padding({ bottom: 12 });
Row() {
Image($r('app.media.huawei')).width(32).height(32).margin({ right: 12 });
};
}
.padding({ top: 24 });
}.backgroundColor('#FFF0F0F0')
.padding(24)
.width(480)
.border({ radius: '10%' });
}
@Entry
@Component
struct Index {
private ctx: UIContext = this.getUIContext();
private contentNode: ComponentContent<Object> =
new ComponentContent(this.ctx, wrapBuilder(buildText));
aboutToAppear(): void {
PromptActionClass.setContext(this.ctx);
PromptActionClass.setContentNode(this.contentNode);
PromptActionClass.setOptions({ alignment: DialogAlignment.Center });
}
build() {
Column() {
Button('已有账号登录')
.margin({ bottom: 24 })
.onClick(() => {
PromptActionClass.openDialog();
});
}
.justifyContent(FlexAlign.End)
.width('100%')
.height('100%');
}
}