在日常开发中,Activity中可能有比较复杂的布局,比如嵌套很多Fragment,所以针对该需求,通常的做法为放到Activity中统一处理。

常规思路为在dispatchTouchEvent中不拦截MotionEvent,但是会根据event是否落在EditText中做相应的处理,具体做法为

    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        if (ev.getAction() == MotionEvent.ACTION_DOWN) {            View v = getCurrentFocus();            if (isShouldHideInput(v, ev)) {                hideInputMethod(this, v);            }        }        return super.dispatchTouchEvent(ev);    }    private boolean isShouldHideInput(View v, MotionEvent event) {        if (v != null && (v instanceof EditText)) {            int[] leftTop = {0, 0};            v.getLocationInWindow(leftTop);            int left = leftTop[0], top = leftTop[1], bottom = top + v.getHeight(), right = left                    +                    v.getWidth();            if (event.getX() > left && event.getX() < right                    && event.getY() > top && event.getY() < bottom) {                return false;            } else {                return true;            }        }        return false;    }    private Boolean hideInputMethod(Context context, View v) {        v.clearFocus();        InputMethodManager imm = (InputMethodManager)context                .getSystemService(Context.INPUT_METHOD_SERVICE);        if (imm != null) {            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);        }        return false;    }

在Down事件时如果event不在当前获取焦点的EditText中,则收起键盘,另外清除焦点,注意EditText的parent需要设置如下属性保证可以获取焦点,一般直接设置在activity的顶层布局中

android:focusable="trur"android:focusableInTouchMode="trur"

如上处理后会发现用户在EditText间切换焦点时不正常,键盘会出现先收起再弹出,我们要做的是能判断MotionEvent消费后是否由其它EditText获取到了焦点,如果是的话则不收起键盘。

当用户点击其它EditText时,只有Up事件发生时才会完成focus切换,所以做法有两种,第一种比较简单,延时200ms再判断就可以覆盖绝大部分场景,不过会出现用户按住其它EditText时键盘收起等情况。

    private boolean hideInputMethod(Context context, View v) {        // 延时100ms判断焦点是否还在edittext,不在的话则隐藏键盘        mHandler.postDelayed(() -> {            View current = getCurrentFocus();            if (current == v) {                v.clearFocus();                InputMethodManager imm = (InputMethodManager)context                        .getSystemService(Context.INPUT_METHOD_SERVICE);                if (imm != null) {                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                }            }        }, 200);        return false;    }

另外一个更好的方法是在dispatchTouchEvent中监听焦点的变化,如果down和up时焦点无变化,则认为需要收起键盘,与上面类似。具体代码如下

    boolean pendingCollapseKeyword = false;    View focusedView;    // 点击非输入框位置优先隐藏软键盘    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        if (ev.getAction() == MotionEvent.ACTION_DOWN) {            pendingCollapseKeyword = isShouldHideInput(ev);            if (pendingCollapseKeyword) focusedView = getCurrentFocus();        } else if (ev.getAction() == MotionEvent.ACTION_UP) {            if (pendingCollapseKeyword) {                hideInputMethod(this);            }        }        return super.dispatchTouchEvent(ev);    }    private boolean isShouldHideInput(MotionEvent event) {        View v = getCurrentFocus();        if (v instanceof EditText) {            int[] location = {0, 0};            v.getLocationInWindow(location);            return event.getX() < location[0]                   || event.getX() > location[0] + v.getWidth()                   || event.getY() < location[1]                   || event.getY() > location[1] + v.getHeight();        }        return false;    }    // 抬起手指时如果焦点还在原来的EditText则收起键盘    private void hideInputMethod(Context context) {        View v = getCurrentFocus();        if (v == focusedView) {            focusedView.clearFocus();            InputMethodManager imm = (InputMethodManager)context                    .getSystemService(Context.INPUT_METHOD_SERVICE);            if (imm != null) {                imm.hideSoftInputFromWindow(focusedView.getWindowToken(), 0);            }        }    }

如上同时兼顾了两个需求

  1. 点击EditText外收起键盘
  2. 点击其它EditText保持键盘状态不变

更多相关文章

  1. TextView文字横向自动滚动(跑马灯)
  2. RN中解决键盘问题- 将tab navigation顶起来
  3. 使用jQuery Mobile的注意事项
  4. android EditText属性详解
  5. Android(安卓)- 判断当前网络环境、隐藏软键盘、动态监测及获取
  6. Android软键盘一些处理
  7. android 软件盘相关
  8. 关于Android中Animation的停止
  9. Android(安卓)软键盘盖住输入框或者布局的解决办法

随机推荐

  1. Android:+WebView+demo
  2. Android小技巧收集
  3. Android中通过pid获取app包名
  4. Android(安卓)笑话+html 实例开发(详解)
  5. android activity 基类 通用方法
  6. android:windowIsTranslucent
  7. android 创建快捷方式图标到桌面
  8. Android中对图像进行Base64编码
  9. android监听按钮的点击事件
  10. Android(安卓)canvas.drawArc() 画圆弧