andorid学习笔记(五):点击EditView之外的关闭软键盘

前提:

今天遇到了一个需求,布局中有一个EditView,当我编辑完内容之后,都需要手动的将软键盘点掉或者通过返回键才能关闭这个软键盘,对于大部分app的使用来说,基本上都是你点完输入框,输入完内容,点击其它无关紧要的空白部分就可以关闭软键盘,所以我也想实现这个功能。

实现:

一、

先给出关闭软键盘的代码块:

public void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        // 隐藏软键盘
        imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
    }

调用这个方法之后就会让当前页面中的软键盘关闭。小小说一下上面两行,对我来说蛮陌生的用法,cv大哥可以直接跳过

InputMethodManager:用来管理输入法的类,主要用在软键盘的显示和隐藏,它的主要方法有

public boolean showSoftInput(View view, int flags)

显示软键盘,第一个参数view是指针对哪个视图来显示这个软键盘,第二个是个标识符,基本上都是0;

public boolean hideSoftInputFromWindow(IBinder windowToken, int flags) {
        return hideSoftInputFromWindow(windowToken, flags, null);
    }

隐藏软键盘,也就是我们上面代码用到的方法,我们需要传的参数有windowToken,直译过来的是一个Ibinder类型的窗口句柄,这就有点涉及到底层了,盲区啊!但是我猜测只是想传递个当前是哪个窗口这样子,吧?

getSystemService:这个方法用于获取android的系统服务,参数只有一个name,也就是想要获取的系统服务的名称,通常在Context下的一个常量,比如:

Context.WINDOW_SERVICE:窗口管理服务。
Context.LAYOUT_INFLATER_SERVICE:布局加载服务。
Context.ACTIVITY_SERVICE:活动管理服务。
Context.POWER_SERVICE:电源管理服务。
Context.ALARM_SERVICE:定时器管理服务。
Context.NOTIFICATION_SERVICE:通知管理服务。
Context.KEYGUARD_SERVICE:键盘锁管理服务。
Context.LOCATION_SERVICE:位置管理服务。
Context.CONNECTIVITY_SERVICE:网络连接服务。
Context.VIBRATOR_SERVICE:震动服务。
Context.INPUT_METHOD_SERVICE:输入法管理服务。

返回的类型是一个Object,一般根据需要的服务来强转类型。

getWindow()和getDecorView(),在我们自己的布局文件之上其实还被两个东西包裹,也就是这个DecorView还有Window,这个我也讲不明白,不过我知道有这两个东西。

二、

在你这个页面的根布局设置一个点击事件

mBinding.scoreLinear.setOnTouchListener((v, event)  -> {
                hideKeyboard();
                View currentFocus = getCurrentFocus();
                if (currentFocus !=null)currentFocus.clearFocus();
                return false;
            });

其实核心就只有上面那个调用软键盘隐藏,原理就是如果你点击的是其它view组件,它们有自己的事件处理机制,也就是有自己的onClick方法,如果点击事件在他们自己的作用范围,事件会在它们本身的onClick进行消费,只有在没有点击事件或者其它事件的情况下被点击,就会触发这个根布局的点击事件,另外我还在其中多写了一个功能,因为EditView的TextChangeListener三个方法都没法满足我想要在收回键盘后光标消失的功能,所以,我在这个根布局的点击方法中添加了当我的焦点不为空的时候,清除本页面的所有焦点。

另外,为什么我说的是点击事件但是实际上我放出来的代码是一个触摸事件呢,原因是因为笔者的布局问题,我的最外层点击事件被第二层的ScrollView的滑动事件拦截了,就是它们布局重叠的那块,如果我是设置在最外层的布局点击事件,那么一直会在传到它消费之前就已经被ScrollView消费返回了,遇到这个问题的时候才觉得,emmmm,确实系统的事件分发也有不够用的时候,知识到用时方恨少啊,对事件处理和分发还是薄弱了点,希望大家也能好好的去深入理解这个过程!

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值