HarmonyOS鸿蒙Next中Toast Dialog弹出时不获焦、不抢焦的方法

HarmonyOS鸿蒙Next中Toast Dialog弹出时不获焦、不抢焦的方法

通过this.promptAction.openCustomDialog利用弹窗实现自定义toast,在弹窗展示后,输入框的失焦,是否有办法让弹窗不获焦?

操作步骤:

  1. 输入框获焦键盘弹起
  2. 出现自定义弹窗后,输入框失焦键盘收起
  3. 弹窗消失后,才重新获焦
3 回复

通过this.promptAction.openCustomDialog+builder形式实现自定义toast的话,可以通过对builder中元素设置失焦(focusable(false)),可以实现所说的失焦。

参考代码:

import { hilog } from '@kit.PerformanceAnalysisKit'
import { promptAction } from '@kit.ArkUI'

let customDialogId: number = 0

@Component
struct Index {
  @Builder
  customDialogBuilder() {
    Column() {
      Text('Custom dialog Message').fontSize(10)
      Row() {
        Button("确认").onClick(() => {
          promptAction.closeCustomDialog(customDialogId)
        })
        Blank().width(50)
        Button("取消").onClick(() => {
          promptAction.closeCustomDialog(customDialogId)
        })
      }
    }
    .focusable(false)
  }

  build() {
    Column() {
      FourTextInput({
        onFinishInput: () => {
          console.log('finish')
          promptAction.openCustomDialog({
            builder: () => {
              this.customDialogBuilder()
            },
          })
        }
      })
    }
  }
}

@Component
struct FourTextInput {
  onFinishInput?: (value: string) => void
  @State inputValue: string[] = ["", "", "", ""]
  @State inputEnable: boolean[] = [true, false, false, false]
  inputIndex: number[] = [0, 1, 2, 3]

  build() {
    Row() {
      ForEach(this.inputIndex, (index: number) => {
        RelativeContainer() {
          TextInput({ text: this.inputValue[index] })
            .layoutWeight(1)
            .textInputStyle(this.inputEnable[index])
            .maxLength(1)
            .maxLines(1)
            .id(index.toString())
            .type(InputType.Number)
            .onDidDelete((_) => {
              if (this.inputValue[index].length == 0) {
                if (index != 0) {
                  this.inputValue[index-1] = ""
                  this.inputEnable[index] = false
                  this.inputEnable[index-1] = true
                  this.getUIContext().getFocusController().requestFocus((index - 1).toString())
                } else {
                  this.inputValue[index] = ""
                }
              }
            })
            .onChange((value: string, previewText?: PreviewText) => {
              this.inputValue[index] = value
              if (value.length == 1) {
                if (index != 3) {
                  this.inputEnable[index+1] = true
                  this.getUIContext().getFocusController().requestFocus((index + 1).toString())
                  this.inputEnable[index] = false
                } else {
                  if (this.onFinishInput) {
                    let result = ""
                    for (let i = 0; i < this.inputValue.length; i++) {
                      result += this.inputValue[i]
                    }
                    this.onFinishInput(result)
                  }
                }
              }
            })
          if (!this.inputEnable[index]) {
            Text().backgroundColor(Color.Transparent).alignRules({
              left: { anchor: index.toString(), align: HorizontalAlign.Start },
              top: { anchor: index.toString(), align: VerticalAlign.Top },
              bottom: { anchor: index.toString(), align: VerticalAlign.Bottom },
              right: { anchor: index.toString(), align: HorizontalAlign.End }
            })
          }
        }.layoutWeight(1).height(40).margin({ right: index == this.inputIndex.length - 1 ? 0 : 10 })
      })
    }.onAppear(() => {
      this.getUIContext().getFocusController().requestFocus("0")
    })
  }
}

@Extend(TextInput)
function textInputStyle(enable: boolean) {
  .border({
    width: 1,
    color: enable ? "#1b91e0" : "#999999",
    radius: 4,
    style: BorderStyle.Solid,
  })
  .textAlign(TextAlign.Center)
  .layoutWeight(1)
  .maxLength(1)
  .maxLines(1)
  .type(InputType.Number)
  .layoutWeight(1)
  .height(40)
}

更多关于HarmonyOS鸿蒙Next中Toast Dialog弹出时不获焦、不抢焦的方法的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,Toast Dialog默认不会获取焦点或抢占焦点。若需确保Toast Dialog不获焦、不抢焦,可通过设置WindowManager.LayoutParamsFLAG_NOT_FOCUSABLEFLAG_NOT_TOUCHABLE标志来实现。具体代码示例如下:

let toastDialog = new ToastDialog(context);
let window = toastDialog.getWindow();
let layoutParams = window.getAttributes();
layoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
window.setAttributes(layoutParams);
toastDialog.show();

此方法确保Toast Dialog显示时不会干扰当前焦点。

在HarmonyOS Next中,可以通过设置Dialog的focusable属性为false来实现Toast弹窗不获焦。具体实现方式如下:

  1. 在自定义Dialog的构造方法中设置:
constructor(context: Context) {
    super(context);
    this.setFocusable(false);  //关键设置
}
  1. 或者在使用时动态设置:
let dialog = new CustomDialog(context);
dialog.setFocusable(false);
dialog.show();
  1. 对于使用promptAction.openCustomDialog的情况,可以通过配置参数实现:
this.promptAction.openCustomDialog({
    focusable: false,  //禁止获焦
    //其他参数...
});

这样设置后,弹窗显示时将不会夺取输入框的焦点,键盘也不会收起。注意需要确保弹窗内容本身不需要交互,因为设为不获焦后用户将无法操作弹窗内的元素。

回到顶部