道家人 发表于 2025-2-23 16:21:29

【HarmonyOS NEXT】解决自界说弹框和键盘之间安全隔断的问题

【HarmonyOS NEXT】解决自界说弹框和键盘之间安全隔断的问题

一、问题背景

https://i-blog.csdnimg.cn/direct/455198ef669140ffb4c8a286ed6ce3a5.png
我们在应用开辟批评输入框时,常规的需求样式是:输入框view和键盘贴近,上半部展示信息区的形式,这样的计划,方便用户不割裂的去批评发言。
但是在利用鸿蒙提供的自界说弹框时,会发现键盘和弹框之间有个安全安定。就算弹框结构是置底,每次表现键盘都会将弹框顶上去。
https://i-blog.csdnimg.cn/direct/33a862ccaca74926a2f36e5e8df28ade.png
自界说弹框源码
@CustomDialog
@Component
struct CustomDialogExample {
@Link textValue: string
@Link inputValue: string

controller?: CustomDialogController
cancel: () => void = () => {
}
confirm: () => void = () => {
}

build() {
    Column() {
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
      .onChange((value: string) => {
          this.textValue = value
      })
      .defaultFocus(true)
      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
      Button('cancel')
          .onClick(() => {
            if (this.controller != undefined) {
            this.controller.close()
            this.cancel()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
      Button('confirm')
          .onClick(() => {
            if (this.controller != undefined) {
            this.inputValue = this.textValue
            this.controller.close()
            this.confirm()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })

    }.borderRadius(10)
    .height(px2vp(500))
    .offset({ x: 0, y: 16})
}
}
调用页面源码:
@Entry
@Component
struct TextPage {
@State textValue: string = ''
@State inputValue: string = 'click me'
dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: ()=> { this.onCancel() },
      confirm: ()=> { this.onAccept() },
      textValue: $textValue,
      inputValue: $inputValue
    }),
    cancel: this.exitApp,
    autoCancel: true,
    onWillDismiss:(dismissDialogAction: DismissDialogAction)=> {
      console.info("reason=" + JSON.stringify(dismissDialogAction.reason))
      console.log("dialog onWillDismiss")
      if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
      dismissDialogAction.dismiss()
      }
      if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
      dismissDialogAction.dismiss()
      }
    },
    keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
    alignment: DialogAlignment.Bottom,
    // offset: { dx: 0, dy: -20 },
    gridCount: 4,
    customStyle: false,
    cornerRadius: 10,
    backgroundColor: Color.Black
})

// 在自定义组件即将析构销毁时将dialogController置空
aboutToDisappear() {
    this.dialogController = null // 将dialogController置空
}

onCancel() {
    console.info('Callback when the first button is clicked')
}

onAccept() {
    console.info('Callback when the second button is clicked')
}

exitApp() {
    console.info('Click the callback in the blank area')
}
build() {
    Column() {
      Button(this.inputValue)
      .onClick(() => {
          if (this.dialogController != null) {
            this.dialogController.open()
          }
      }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
}
}
二、解决方案

相识安全弹框的问题,需要对自界说弹框的实现有比较深刻的熟悉才气规避。
起首我们要搞清晰,自界说弹框的根本用法,会发现在CustomDialogExample中,build是弹框结构的具体样式的一部分,在调用页面TextPage ,实在也会设置弹框的一些样式属性,比方:customStyle。
这是体系体系的根本样式,如果customStyle该属性为false,那我们的弹框样式,只需要关心弹框内的结构,整个弹框外围是交给体系定制样式处置惩罚。
所以当我们设置customStyle该属性为true,就会发现弹框view会贴合键盘,但是整体弹框的边框都没了。
https://i-blog.csdnimg.cn/direct/29574859497c4bf7895b340f29f79bca.png
此时我们只需要处置惩罚边框样式和弹框背景致即可:
.borderRadius(15)
.backgroundColor(Color.White)
.borderWidth(5)
https://i-blog.csdnimg.cn/direct/639920c569eb41b9b070655af736f973.png
源码示例:

自界说弹框源码
@CustomDialog
@Component
struct CustomDialogExample {
@Link textValue: string
@Link inputValue: string

controller?: CustomDialogController

cancel: () => void = () => {
}
confirm: () => void = () => {
}

build() {
    Column() {
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
      .onChange((value: string) => {
          this.textValue = value
      })
      .defaultFocus(true)
      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
      Button('cancel')
          .onClick(() => {
            if (this.controller != undefined) {
            this.controller.close()
            this.cancel()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
      Button('confirm')
          .onClick(() => {
            if (this.controller != undefined) {
            this.inputValue = this.textValue
            this.controller.close()
            this.confirm()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })

    }.width("90%")
    .borderRadius(15)
    .backgroundColor(Color.White)
    .borderWidth(5)
    .height(px2vp(500))
    .offset({ x: 0, y: 16})
}
}
调用页面源码:
@Entry
@Component
struct TextPage {
@State textValue: string = ''
@State inputValue: string = 'click me'
dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: ()=> { this.onCancel() },
      confirm: ()=> { this.onAccept() },
      textValue: $textValue,
      inputValue: $inputValue
    }),
    cancel: this.exitApp,
    autoCancel: true,
    onWillDismiss:(dismissDialogAction: DismissDialogAction)=> {
      console.info("reason=" + JSON.stringify(dismissDialogAction.reason))
      console.log("dialog onWillDismiss")
      if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
      dismissDialogAction.dismiss()
      }
      if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
      dismissDialogAction.dismiss()
      }
    },
    keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
    alignment: DialogAlignment.Bottom,
    gridCount: 4,
    customStyle: true,
    cornerRadius: 10,
    backgroundColor: Color.Black
})

// 在自定义组件即将析构销毁时将dialogController置空
aboutToDisappear() {
    this.dialogController = null // 将dialogController置空
}

onCancel() {
    console.info('Callback when the first button is clicked')
}

onAccept() {
    console.info('Callback when the second button is clicked')
}

exitApp() {
    console.info('Click the callback in the blank area')
}
build() {
    Column() {
      Button(this.inputValue)
      .onClick(() => {
          if (this.dialogController != null) {
            this.dialogController.open()
          }
      }).backgroundColor(0x317aff)
    }.width('100%').margin({ top: 5 })
}
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【HarmonyOS NEXT】解决自界说弹框和键盘之间安全隔断的问题