Android EditText打開輸入法后,點(diǎn)擊任意位置收起輸入法

默認(rèn)情況下,點(diǎn)擊EditText會(huì)打開輸入法。項(xiàng)目中有個(gè)需求功能是點(diǎn)擊其他地方(除鍵盤外)可以關(guān)閉輸入法,第一時(shí)間想到的是,點(diǎn)擊其他View就收起輸入法,那么有個(gè)問(wèn)題,當(dāng)你View很多是時(shí)候,你都要對(duì)每個(gè)View注冊(cè)點(diǎn)擊事件,過(guò)于復(fù)雜。研究出一種方法,記錄一下怎么做的

點(diǎn)擊事件都會(huì)進(jìn)入Activity的dispatchTouchEvent里面,所以可以在Activity的基類里面做處理

  override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    if (ev.action == MotionEvent.ACTION_DOWN) {
      if (isShouldHideKeyboard(currentFocus, ev)) {
        currentFocus?.hideSoftInput()
      }
    }
    return super.dispatchTouchEvent(ev)
  }

  open fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
    if (v is EditText) {
      var result = true
      needFilterHideKeyboardView().forEach {
        result = result && isEventInViewBound(it, event)
      }
      return result && isEventInViewBound(v, event)
    }
    // 如果焦點(diǎn)不是EditText則忽略,這個(gè)發(fā)生在視圖剛繪制完,第一個(gè)焦點(diǎn)不在EditText上,和用戶用軌跡球選擇其他的焦點(diǎn)
    return false
  }

  private fun isEventInViewBound(v: View, event: MotionEvent): Boolean {
    val l = intArrayOf(0, 0)
    v.getLocationInWindow(l)
    val left = l[0]
    val top = l[1]
    val bottom = top + v.height
    val right = left + v.width
    return event.x <= left || event.x >= right || event.y <= top || event.y >= bottom
  }

  open fun needFilterHideKeyboardView(): List<View> = emptyList()

分析:
1、首先判斷點(diǎn)擊事件是否為DOWN,之后再判斷是否收起鍵盤
2、isShouldHideKeyboard中需要處于當(dāng)前焦點(diǎn)的View和事件event
3、判斷當(dāng)前獲取焦點(diǎn)的View的類似是否為EditText,如果不是則不做處理,是的話再判斷
4、添加過(guò)濾的View,即點(diǎn)擊該View不作處理(可以在子Activity里面添加)
5、isEventInViewBound作用是判斷當(dāng)前的點(diǎn)擊是否在這個(gè)View外面,如果點(diǎn)擊不落在該View,則收起輸入法
6、v.getLocationInWindow(l)取到View的X,Y點(diǎn),之后取到View的四個(gè)點(diǎn),如果event的點(diǎn)擊不范圍不在View內(nèi),return true,輸入法收起,否則return false,不作處理
注:currentFocus是當(dāng)前獲取焦點(diǎn)的View,聚焦和點(diǎn)擊是不同的概念,可以理解為聚焦的View是光標(biāo)閃爍的View

關(guān)于hideSoftInput()

fun View.hideSoftInput() { // 關(guān)閉輸入法
  (BaseApplication.appContext.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
    hideSoftInputFromWindow(windowToken, 0)
  }
  this.clearFocus()
}

在Kotlin中可以添加擴(kuò)展方法,把你需要的操作放入擴(kuò)展方法里面,之后直接調(diào)去就好了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容