Android软键盘与EditText



Android 应用开发必不可少的涉及软键盘操作,也不可避免的遇到一些问题,这里主要总结主要针对几种不同的场景,分享相应的处理经验;

有一个很常见的需求,就是页面中软键盘打开时,希望能点击屏幕其他的任何位置,就能把软键盘给隐藏掉. 
比如登录, 注册之类的常见页面. 
在实际开发中,很多童鞋是这样做的,通过其他控件的点击事件,在onclick方法中调用隐藏软键盘的方法,从而达到相应效果,但是在页面复杂的时候,要实现的onclick方法会很多,甚至还会有逻辑处理冲突的情况.这样做就显得非常不友好.


今天,纯洁的我,就针对这样的情况,给各位大佬分享,怎样通过一行代码实现软键盘与EditText的交互.

先看效果图 
这里写图片描述

是不是觉得效果很棒,而且实现方式简单,只要一行代码你就可以把这种效果带回家. 
什么?不信?

上码

    @Override
    public int[] hideSoftByEditViewIds() {
        int[] ids = {R.id.et_phone, R.id.et_check_code, R.id.et_city_code};
        return ids;
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

我们只要在hideSoftByEditViewIds()方法中直接return int数组即可,int值为editText的id,然后就完成了. 
真的可以了嘛?是的! 
不过作为一个有格调的程序员,几行代码实现写个博客不符合我的逼格. 
所以我们还是先简单介绍具体实现的原理.


原理 : 就是重写Activity的dispatchTouchEvent(MotionEvent ev)方法,全局监听触摸事件, 当点击的页面时,发现如果焦点在EditView上,就把软键盘隐藏,否则就不做处理.

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
              //获取焦点View
              View v = getCurrentFocus();
            if (isFocusEditText(v, hideSoftByEditViewIds())) {
                //如果焦点在editText上
                //隐藏键盘
                KeyBoardUtils.hideInputForce(this);
                //清除焦点
                clearViewFocus(v, hideSoftByEditViewIds());
            }
        }
        return super.dispatchTouchEvent(ev);

    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

就是这么简单,如果觉得在每个Activity中重写dispatchTouchEvent太麻烦,大佬们也可以把它放到BaseActivity里面,最后只要暴露出hideSoftByEditViewIds()方法即可.


扩展: 有时候,我们的需求可能并不是点击所有其他控件就隐藏软键盘,这时候,就需要对一部分控件过滤,考虑这样的情况,我这里也做了处理.

   //是否触摸在指定view上面,对某些控件过滤
    public boolean isTouchView(View[] views, MotionEvent ev) {
        if (views == null || views.length == 0) return false;
        int[] location = new int[2];
        for (View view : views) {
            view.getLocationOnScreen(location);
            int x = location[0];
            int y = location[1];
            if (ev.getX() > x && ev.getX() < (x + view.getWidth()) && ev.getY() > y && ev.getY() < (y + view.getHeight())) {
                return true;
            }
        }
        return false;
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

然后修改dispatchTouchEvent(MotionEvent ev),如下

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             //如果点击了过滤的控件,就不做处理 
            if (isTouchView(filterViewByIds(), ev)) return super.dispatchTouchEvent(ev);
            //如果传入的editText的id为空,也不做处理
            if (hideSoftByEditViewIds() == null || hideSoftByEditViewIds().length == 0)
                return super.dispatchTouchEvent(ev);
            //获取焦点所在view
            View v = getCurrentFocus();
            if (isFocusEditText(v, hideSoftByEditViewIds())) {
            //如果焦点在传入的editText上
                //隐藏键盘
                KeyBoardUtils.hideInputForce(this);
                //清除焦点
                clearViewFocus(v, hideSoftByEditViewIds());
            }
        }
        return super.dispatchTouchEvent(ev);

    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

同样使用很简单,我们只要filterViewByIds()方法,然后传入要过滤的view即可.Fragment中原理一样. 
很简单吧.本身实现这样的方式很多种,这里只是一种方式,如果有大佬觉得我没讲述清楚的,可以看具体代码 
代码传送门



附加

这里附加一些用到的方法,知道的大佬可以略过

1. 软键盘的操作方法,大家都知道,参数大同小异,比如下面一种:

    /**
     * des:隐藏软键盘,这种方式参数为activity
     *
     * @param activity
     */
    public static void hideInputForce(Activity activity) {
        if (activity == null || activity.getCurrentFocus() == null)
            return;

        ((InputMethodManager) activity.getSystemService(INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(activity.getCurrentFocus()
                        .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
   /**
     * 打开键盘
     * @param context
     **/
    public static void showInput(Context context, View view) {
        InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            view.requestFocus();
            imm.showSoftInput(view, 0);
        }
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.软键盘弹出时会覆盖页面内容 
在Manifest中设置android:windowSoftInputMode属性即可,如下代码,具体适用,大佬们可自行百度android:windowSoftInputMode.

  <activity 
   android:name=".MainActivity"
   android:windowSoftInputMode="adjustResize"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值