点击非 EditText 区域时隐藏输入法的实现

有个常见的需求,就是在页面上编辑时打开输入法,点击其他位置时收起输入法。
我们可以在基类的 Activity 去实现这个需求:

abstract class BaseActivity : AppCompatActivity() {

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (shouldHideSoftInput(ev)) hideSoftInput()
        return super.dispatchTouchEvent(ev)
    }
    
    /** 当前事件[ev]是否应该隐藏输入法 */
    private fun shouldHideSoftInput(ev: MotionEvent): Boolean {
        return ev.action == MotionEvent.ACTION_DOWN
                && !isInEditTextRange(ev.x.toInt(), ev.y.toInt())
    }
    
    /** 指定位置([x],[y])是否在 EditText 的范围中 */
    private fun isInEditTextRange(x: Int, y: Int): Boolean {
        window.decorView.getFocusables(View.FOCUS_FORWARD).forEach {
            if (it.visibility == View.GONE) return@forEach
            if (it is EditText && isInViewRange(it, x, y)) return true
        }
        return false
    }
    
    /** 指定位置([x],[y])是否在视图[view]的范围中 */
    private fun isInViewRange(view: View, x: Int, y: Int): Boolean {
        val leftTop = IntArray(2)
        view.getLocationInWindow(leftTop)
        val left = leftTop[0]
        val top = leftTop[1]
        val bottom = top + view.height
        val right = left + view.width
        return x in left..right && y in top..bottom
    }
    
    /** 隐藏输入法 */
    private fun hideSoftInput() {
        val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManag
        imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
    }
}

实现思路是对所有可获取焦点的视图进行遍历,判断触摸点是否在可见的 EditText 范围内,如果不是则隐藏输入法。
使用这种写法,软键盘不会在多个 EditText 之间切换焦点时重复关闭打开。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值