在HarmonyOS NEXT开发中获取焦点弹出键盘后,点击空白区域不能自动取消焦点?

在HarmonyOS NEXT开发中获取焦点弹出键盘后,点击空白区域不能自动取消焦点?

阅读 930
avatarAI BotBETA

解决方案:

在ArkUI中需要手动处理点击空白区域隐藏键盘的操作,可以通过以下两种方式实现:

方法1:全局点击监听

// 在build方法外层声明控制器
@State inputText: string = ''
controller: TextInputController = new TextInputController()

build() {
  Column() {
    TextInput({ text: this.inputText, controller: this.controller })
      .onFocus(() => {
        this.controller.showSoftKeyboard()
      })
  }
  // 添加整个Column的点击事件
  .onClick(() => {
    // 通过焦点系统获取当前焦点控件
    let focusNode = focusControl.getCurrentFocus()
    if (focusNode) {
      focusNode.blur()
      this.controller.hideSoftKeyboard()
    }
  })
}

方法2:使用焦点控制模块

import { focusControl } from '@ohos.arkui.focus'

// 在适当的位置添加焦点监听
focusControl.onFocusChange((oldNode, newNode) => {
  if (!newNode) { // 当焦点变为空时隐藏键盘
    this.controller.hideSoftKeyboard()
  })
})

// 点击空白区域时主动清空焦点
Column()
  .onClick(() => {
    focusControl.clearFocus()
  })

关键点说明:

  1. HarmonyOS NEXT的焦点系统需要显式控制
  2. 软键盘显示状态需要与焦点状态绑定
  3. 使用focusControl模块可以获取当前焦点状态
  4. 通过blur()方法或clearFocus()可以主动取消焦点
  5. 建议配合HitTestMode.Transparent处理复杂布局的穿透点击

扩展建议:
对于复杂页面可以使用自定义弹窗组件封装该逻辑:

@Component
struct AutoDismissKeyboard {
  build() {
    Column() {
      // 内容区域
      Column() {
        // 这里放置表单内容...
      }
      .layoutWeight(1)

      // 底部操作区域
      Button('确认')
    }
    .width('100%')
    .height('100%')
    .onClick(() => {
      focusControl.clearFocus()
    })
    .hitTestBehavior(HitTestMode.Transparent)
  }
}
1 个回答

可以通过空白部分的点击事件,动态的修改TextInput的属性不可获焦,然后通过TextInput的点击事件设置可获焦。或者通过转移焦点到其他非关键组件上使当前TextInput失焦

@Entry 
@Component 
struct FocusableExample { 
  @State inputValue: string = '' 
  @State textInputFocusAble: boolean = true; 
  controller: TextInputController = new TextInputController() 
 
  build() { 
    Column() { 
      TextInput({ placeholder: 'wait input...', text: '', controller: this.controller }) 
        .id("textInput") 
        .focusable(this.textInputFocusAble) 
        .margin({ top: 150 }) 
    } 
    .onClick(() => { 
      this.textInputFocusAble = false; 
      let setFocusAble = setInterval(() => { 
        this.textInputFocusAble = true; 
        clearInterval(setFocusAble) 
      }, 100) 
    }) 
    .backgroundColor(Color.Grey) 
    .height("100%") 
  } 
}