0
点赞
收藏
分享

微信扫一扫

Android实战开发篇 点击EditText以外区域,隐藏键盘,失去焦点

SPEIKE 2022-04-24 阅读 136

一、建立软键盘监听

 	/**
     * 软键盘监听器
     */
    public static class SoftKeyBoardListener {
    	//activity的根视图
        private View rootView;
        //记录根视图的显示高度
        int rootViewVisibleHeight;
        
        private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;

        public SoftKeyBoardListener(Activity activity) {
            //获取activity的根视图
            rootView = activity.getWindow().getDecorView();

            //监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
            rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    //获取当前根视图在屏幕上显示的大小
                    Rect r = new Rect();
                    //获取rootView在窗体的可视区域
                    rootView.getWindowVisibleDisplayFrame(r);
                    int visibleHeight = r.height();
                    if (rootViewVisibleHeight == 0) {
                        rootViewVisibleHeight = visibleHeight;
                        return;
                    }

                    //根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
                    if (rootViewVisibleHeight == visibleHeight) {
                        return;
                    }

                    //根视图显示高度变小超过200,可以看作软键盘显示了
                    if (rootViewVisibleHeight - visibleHeight > 200) {
                        if (onSoftKeyBoardChangeListener != null) {
                            onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
                        }
                        rootViewVisibleHeight = visibleHeight;
                        return;
                    }

                    //根视图显示高度变大超过200,可以看作软键盘隐藏了
                    if (visibleHeight - rootViewVisibleHeight > 200) {
                        if (onSoftKeyBoardChangeListener != null) {
                            onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
                        }
                        rootViewVisibleHeight = visibleHeight;
                        return;
                    }

                }
            });
        }

        private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
            this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
        }
		
		/**
		 * 软键盘监听接口
		 */
        public interface OnSoftKeyBoardChangeListener {
        	// 键盘显示
            void keyBoardShow(int height);
            // 键盘隐藏
            void keyBoardHide(int height);
        }

        public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
            SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
            softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
        }

    }

二、重写dispatchTouchEvent [ Activity/Fragment ]

    @Override
    public boolean dispatchTouchEvent(MotionEvent motionEvent) {
        if (motionEvent.getAction() == 0) {
            View v = getCurrentFocus();
            if (isShouldHideInput(v, motionEvent) && keyboardIsShown) {
                hideSoftInput(v.getWindowToken());
            }
        }
        return super.dispatchTouchEvent(motionEvent);
    }
	
	// 隐藏键盘
    private void hideSoftInput(IBinder token) {
        if (token != null) {
            InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            im.hideSoftInputFromWindow(token,
                    InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    private boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (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();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击EditText的事件,忽略它。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditView上,和用户用轨迹球选择其他的焦点
        return false;
    }

三、EditText失去焦点 [ clearFocus() ]

   mEditText.clearFocus();

四、具体使用

public static boolean keyboardIsShown = false;

@Override
public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    
     SoftKeyBoardListener.setListener(this, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
        @Override
        public void keyBoardShow(int height) {
            keyboardIsShown = true;
        }
        @Override
        public void keyBoardHide(int height) {
        	mEditText.clearFocus(); // 对应EditText失去焦点
            keyboardIsShown = false;
        }
    });
}

五、其他 [ 设置只能输入数字和小数点 ]

关键点:android:inputType=“number”

// 纯数字
<EditText
     android:hint="请输入验证码"
     android:inputType="number"
     android:digits="@string/filter_vcode"/>

// 小数点
<EditText
     android:hint="请输入验证码"
     android:inputType="numberDecimal"
     android:digits="@string/filter_vcode"/>

代码形式:

// 1.如果设置只输入数字
edittext.setInputType( InputType.TYPE_CLASS_NUMBER);
//此时只会弹出数字输入框,符号点击后不会输入到文字框中

//2.只能输入数字和小数点
edittext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
//此时注意:只设置InputType.TYPE_NUMBER_FLAG_DECIMAL是无法实现只能输入数字和小数点的,必须InputType.TYPE_CLASS_NUMBER 和InputType.TYPE_NUMBER_FLAG_DECIMAL同时设置才可以

其他输入正则参考链接:EditText输入正则

六、软键盘遮挡问题方案

1.Activity内设置

//在Activity中的oncreate中setContentView之前写上这个代码
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

2.AndroidManifest.xml

//在AndroidManifest.xml对应的Activity里添加 
android:windowSoftInputMode="adjustPan"或是android:windowSoftInputMode="adjustResize"属性 

在这里插入图片描述
详细解析可参考:5种方法完美解决android软键盘挡住输入框方法详解

举报

相关推荐

0 条评论