Android 监听EditText输入框软键盘显示及隐藏

目录

前言

 一、软键盘监听原理

 二、软键盘监听代码


前言

最近做项目遇到一个比较坑的难点问题。需求是在结算页面中,有个金额输入框,不管用户输入什么数字,都保留2位小数并在输入框中显示出来。如下图:

首先,我们知道EditText可以通过设置   android:inputType="numberDecimal" 软键盘为带小数点的数字。还有,通过对EditText添加文本改变监听事件TextWatcher,在文本改变后会回调afterTextChanged(),在这个方法中对EditText的值进行类型转换并通过 String.format("%.2f", value) ,保留2位。 这样实现行不行呢?

答案,肯定不行。因为,文本只要变化就强制保留2位,会遇到一个问题,就是小数位输入体验极差。比如,先输如 “1”, 这时文本转换后显示“1.00” ,再想输入小数位是不是得进行删除一个“0”,但是一旦删除就会触发文本改变的监听事件,就又强制显示成“1.00”,除非是让用户把光标移到到小数点后去写。

那么,我们使用失去焦点的方案行不行呢?答案,是可以的,只不过有点瑕疵。首先,给EditText设置焦点监听setOnFocusChangeListener回调onFocusChange(view,hasFocus),然后调用clearFocus()失去焦点。但是,要想让输入框失去焦点就得找落脚点了,一般最好是选择Activity的根视图。但是想一想,用户此时是软键盘悬浮在页面下方,肯定点击收起软键盘的按钮,而这个按钮的事件响应并没开放。


 一、软键盘监听原理

由于,安卓系统并没有提供软键盘弹入和弹出的方法。所以,我们需要自己自定义一个监听软件盘的类。大致实现原理就是监听视图树中布局或可视状态发生改变超过一定的数值,认定软键盘进行了弹出\收起事件了。

1、获取根视图rootView

View rootView =this.getWindow().getDecorView();

2、获取根视图屏幕高度

Rect r = new Rect(); 
rootView.getWindowVisibleDisplayFrame(r);
int currentVisibleHeight = r.height();

int rootViewVisibleHeight = visibleHeight;//拷贝一份,用于比较值的改变

3、监听布局树视图改变

 rootView.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {

            }
}

4、判断软键盘改变

这里是比较关键的地方。这个的200是高度,是用来判断软键盘改变的布局高度变化值,可以根据具体情况改变值大小。因为,初始化时我们先将根视图高度进行了拷贝一份用来判断。

如果展开了,那么当前根视图的高度会比之前小的,这里判断比之前小了200以上,即为软键盘——弹出。

if (rootViewVisibleHeight - currentVisibleHeight > 200) {
    rootViewVisibleHeight = visibleHeight;
    //软键盘——弹出
    return;
}

if (currentVisibleHeight - rootViewVisibleHeight > 200) {
    rootViewVisibleHeight = visibleHeight;
    //软键盘——收起
    return;
 }

二、软键盘监听代码

 

1、清单文件设置configChanges

<activity android:name=".MainActivity"
            android:launchMode="singleTop"
            android:configChanges="keyboardHidden"
            android:windowSoftInputMode="adjustPan|stateHidden"/>

2、 创建接口

public interface OnSoftKeyBoardChangeListener {
        void keyBoardShow();
        void keyBoardHide();
}

3、创建软键盘监听类

public class SoftKeyBoardListener {
    //activity的根视图
    private View rootView;
    //纪录根视图的显示高度
    private int rootViewVisibleHeight;
    //接口回调
    private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
    
    private Activity context;
    private SoftKeyBoardListener(Activity context){
        this.context = context;
        init(context);
    }
    private void init(Activity activity) {
        rootView = activity.getWindow().getDecorView();
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                rootView.getWindowVisibleDisplayFrame(r);
                int visibleHeight = r.height();

                if (rootViewVisibleHeight == 0) {
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }
                //作软键盘显示/隐藏状态没有改变
                if (rootViewVisibleHeight == visibleHeight) {
                    return;
                }

                if (rootViewVisibleHeight - visibleHeight > 200) {
                    if (onSoftKeyBoardChangeListener != null) {
                        onSoftKeyBoardChangeListener.keyBoardShow();
                    }
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }

                if (visibleHeight - rootViewVisibleHeight > 200) {
                    if (onSoftKeyBoardChangeListener != null) {
                        onSoftKeyBoardChangeListener.keyBoardHide();
                    }
                    rootViewVisibleHeight = visibleHeight;
                    return;
                }

            }
        });
    }

    private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
        this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
    }


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

4、Activity中调用

SoftKeyBoardListener.setListener(MainActivity.this, 
      new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
            @Override
            public void keyBoardShow() {
                Log.e("soufkeyboard", "键盘弹出");
            }

            @Override
            public void keyBoardHide(int height) {
                Log.e("soufkeyboard", "键盘收起");
            }
        }
);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章