Android 实现点击空白处让EditText失去焦点并收起系统软键盘

废话不多说,直接上解决思路:

这里我的解决思路就是通过事件的分发来判断手指点下的位置,是不是editText。如果点击的是editText那么就按照原来正常进行;如果点击的不是editText那么就应该让editText失去焦点并收起键盘。所以一共有三个点:

  1. 在哪里截取点击事件并进行处理?
  2. 如何判断点击位置是否为editText的位置?
  3. 如何收起软键盘并让editText失去焦点?

一个一个来看:

  1. 首先我们可以在Activity的dispatchTouchEvent方法中截取点击事件。
    至于为什么,这个是关于点击事件分发的相关内容;简单来说就是每次我们手点击屏幕的时候,系统会生成一个点击事件event并通过dispatchTouchEvent方法来处理,event中就包含有点击的坐标。具体详细的内容有兴趣的读者可以自行了解,这里就不多说了。
  2. 上文说了通过event可以得到点击的位置,那editText的位置呢?通过getCurrentFocus这个方法可以可以获取到当前拥有焦点的view,再通过getLocationInWindow可以获取到在window中的位置;然后进行判断就可以了。如果当前拥有焦点的view不是editText的话则不需要判断。
  3. 这里通过InputMethodManager的hideSoftInputFromWindow方法就可以收起了。

这就是大体的思路,然后接下来看代码实现:

public class EditActivity extends AppCompatActivity {
    private TextInputEditText textInputEditText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit);
        
        textInputEditText = findViewById(R.id.textInputEditText_main);
    }


    //时间分发方法重写
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //如果是点击事件,获取点击的view,并判断是否要收起键盘
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            //获取目前得到焦点的view
            View v = getCurrentFocus();
            //判断是否要收起并进行处理
            if (isShouldHideKeyboard(v, ev)) {
                hideKeyboard(v.getWindowToken());
            }
        }
        //这个是activity的事件分发,一定要有,不然就不会有任何的点击事件了
        return super.dispatchTouchEvent(ev);
    }

    //判断是否要收起键盘
    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        //如果目前得到焦点的这个view是editText的话进行判断点击的位置
        if (v instanceof EditText) {
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            // 点击EditText的事件,忽略它。
            return !(event.getX() > left) || !(event.getX() < right)
                    || !(event.getY() > top) || !(event.getY() < bottom);
        }
        // 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上
        return false;
    }

    //隐藏软键盘并让editText失去焦点
    private void hideKeyboard(IBinder token) {
        textInputEditText.clearFocus();
        if (token != null) {
            //这里先获取InputMethodManager再调用他的方法来关闭软键盘
            //InputMethodManager就是一个管理窗口输入的manager
            InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            if (im != null) {
                im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

}

代码有详细的注释,希望可以帮到你们。
有不懂的地方可以留言

你可能感兴趣的:(学习笔记)