HarmonyOS 鸿蒙Next中如何主动的关闭键盘、弹框,通用方法
HarmonyOS 鸿蒙Next中如何主动的关闭键盘、弹框,通用方法 在App中,可能会存在不同的页面中进行弹框,或者正在输入的情况。
当有一些外部的事件,需要关闭当前的弹框或输入态。
想问一下有没有什么通用的方法可以实现上述的能力,而不是每个页面都需要适配关闭弹框,或输入法面板
【背景知识】 使用弹窗组件时,可优先考虑自定义弹窗,便于自定义弹窗的样式与内容。通过CustomDialogController类显示自定义弹窗,不支持直接在类中定义和使用。通常需要将弹框逻辑封装成Builder或其他组件,以便在需要时调用。
【解决方案】 解决方案一:使用Builder封装自定义弹框。
@CustomDialog
struct CustomDialogExample {
textContent: string = ""
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({ textContent: this.textContent }),
})
build() {
Column() {
Text(this.textContent)
.fontSize(20)
.margin({ top: 10, bottom: 10 })
}
}
}
@Entry
@Component
struct Index {
@Builder
ButtonShowToast(buttonText: string, content: string) {
Button(buttonText)
.onClick(() => {
let dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({ textContent: content }),
})
dialogController.open()
})
}
build() {
Row() {
Column() {
this.ButtonShowToast('test1', '111')
this.ButtonShowToast('test2', '222')
}
}
}
}
解决方案二:使用PromptAction能力,参考文档:openCustomDialog。示例代码如下:
import { PromptAction } from '@ohos.arkui.UIContext';
import { ComponentContent } from '@kit.ArkUI';
import { buildText } from './MyDialog';
@Entry
@Component
struct Index {
private uiContext: UIContext = this.getUIContext()
private promptAction: PromptAction = this.uiContext.getPromptAction();
build() {
Column() {
Button("click me!!!!!!!!!!")
.width('50%')
.type(ButtonType.Capsule)
.backgroundColor(Color.Orange)
.onClick(() => {
// 打开全局自定义弹窗
let contentNode = new ComponentContent(this.uiContext, wrapBuilder(buildText));
this.promptAction.openCustomDialog(contentNode)
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
@CustomDialog
@Component
export struct MyDialog {
controller?: CustomDialogController;
build() {
Column() {
Button("click me!")
.width('50%')
.type(ButtonType.Capsule)
.backgroundColor(Color.Orange)
}
.width('100%')
.height('70%')
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.Blue)
.opacity(0.5)
}
}
@Builder
export function buildText() {
MyDialog()
}
解决方案三:
- 通过GlobalDialogController单例统一管理弹窗。
// 单例模式类,用于管理全局弹窗控制器。
class GlobalDialogController {
_dialogController?: CustomDialogController | null
public static instance: GlobalDialogController | null;
public static getInstance(): GlobalDialogController {
if (!GlobalDialogController.instance) {
GlobalDialogController.instance = new GlobalDialogController();
}
return GlobalDialogController.instance;
}
}
- 通过GlobalDialog组件提供showDialog和hide方法,控制CustomDialogController类显示和隐藏自定义弹窗。
完整示例代码如下:
// 单例模式类,用于管理全局弹窗控制器。
class GlobalDialogController {
_dialogController?: CustomDialogController | null
public static instance: GlobalDialogController | null;
public static getInstance(): GlobalDialogController {
if (!GlobalDialogController.instance) {
GlobalDialogController.instance = new GlobalDialogController();
}
return GlobalDialogController.instance;
}
}
@Entry
@Component
struct Index {
controller: GlobalDialogController = GlobalDialogController.getInstance()
build() {
Row() {
Column({ space: 20 }) {
Button('Toast显示')
.onClick(() => {
// 调用GlobalDialog组件showDialog方法打开弹窗
new GlobalDialog().showDialog('loading。。。', this.controller)
setTimeout(() => {
new GlobalDialog().hide()
}, 2000)
})
}
.width('100%')
}
.height('100%')
}
}
@Component
export struct GlobalDialog {
// 传入instance实例并打开弹窗
showDialog(
msg: string,
instance: GlobalDialogController,
_cancelCallBack?: () => void,
): void {
this.hide()
if (instance) {
instance._dialogController = new CustomDialogController({
builder: _GlobalDialog({ msg: msg }),
autoCancel: false,
cancel: () => {
instance._dialogController = null
if (_cancelCallBack) {
_cancelCallBack()
}
},
customStyle: true,
alignment: DialogAlignment.Center,
maskColor: 0x33000000,
})
instance._dialogController.open()
}
}
// 关闭弹窗
async hide() {
const controller = GlobalDialogController.instance?._dialogController;
if (controller) {
await controller.close();
GlobalDialogController.instance!._dialogController = null;
}
}
aboutToDisappear(): void {
// 清空实例,防止组件销毁后内存泄漏。
GlobalDialogController.instance = null
}
build() {
}
}
@CustomDialog
struct _GlobalDialog {
controller: CustomDialogController
close: () => void = () => {
}
@State msg: string = ""
build() {
Column() {
Text(this.msg)
.fontColor(Color.White)
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.padding(12)
.margin(30)
.borderRadius(10)
.backgroundColor(Color.Black)
}
}
更多关于HarmonyOS 鸿蒙Next中如何主动的关闭键盘、弹框,通用方法的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,可通过调用hide()
方法主动关闭键盘或弹框。对于键盘,使用inputMethodManager.hideSoftInput()
;对于弹框,直接调用其hide()
方法。此方式适用于系统标准组件,无需依赖Java或C语言。
在HarmonyOS Next中,可以通过统一的焦点管理机制实现键盘和弹框的通用关闭。使用FocusManager
的clearFocus()
方法可以主动移除当前焦点,从而自动关闭键盘。对于弹框,建议通过全局事件总线发布关闭事件,各弹框组件订阅该事件并自行处理关闭逻辑。这种方式无需在每个页面单独适配,只需在应用初始化时注册相应的事件监听即可。