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

一、建立软键盘监听

 	/**
     * 软键盘监听器
     */
    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软键盘挡住输入框方法详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

其子昱舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值