Android监听软键盘的显示与隐藏

2017-07-28  本文已影响0人  孟校长
hah.png

前一阵项目开发遇到一个问题。需求是这样的,就是在开播的页面,默认进入展示了两排的标签。标签采用流式布局的形式。展示在直播标题输入框的下面。然后,当用户点击输入框输入文字的时候,这时,软键盘弹出,要求原本在输入框下面的标签布局消失,当用户输入完,返回键使软键盘消失后,标签布局要重新展示出来。刚开始听到这个需求的时候,没觉着有任何的技术难度。无非监听一下软键盘的显示与消失么。当监听到软键盘显示时,将标签布局置为gone;当监听到软键盘消失的时候,再将标签布局置为visible就OK的了。没错,思路完全正确。但是,怎么监听确确实实折腾了我一个下午。

在这里,要和广大朋友声明的一件比较操蛋的事就是,谷歌并没有提供这一类接口来进行软键盘显示与消失的监听。那么,是不是我们就没办法获取这一状态的改变呢?当然不是,我们可以监听根布局的布局高度变化来间接的对软键盘的显示与消失做出判断,并且还可以获取到软键盘的高度(注:当清单文件中windowSoftInputMode="adjustNothing"此方法不生效)。这里有一个知识点还望大家自行科普一下,本篇文章就不做描述了,那就是Android中和软键盘相关的Windowsoftinputmode属性。这里留下一个链接,希望可以帮助到大家。
Windowsoftinputmode属性使用

接下来,直接上代码,代码中我做好了注释,相信应该很容易理解:

public class KeyboardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {

    private static final String TAG = "ListenerHandler";
    private View mContentView;   // 当前界面的根视图
    private int mOriginHeight;   // 此时根视图的高度
    private int mPreHeight;   // 改变之前根视图的高度
    private KeyBoardListener mKeyBoardListen;

    public KeyboardChangeListener(Activity activity) {
        if (activity == null) {
            Log.i(TAG, "contextObj is null");
            return;
        }
        mContentView = findContentView(activity);
        if (mContentView != null) {
            addContentTreeObserver();
        }
    }

    private View findContentView(Activity activity) {
        return activity.findViewById(android.R.id.content);
    }

    private void addContentTreeObserver() {
        mContentView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        // 先获取到当前根视图的高度
        int currHeight = mContentView.getHeight();
        if (currHeight == 0) {
            return;
        }

        boolean hasChange = false;
        if (mPreHeight == 0) {
            mPreHeight = currHeight;
            mOriginHeight = currHeight;
        } else {
            if (mPreHeight != currHeight) {
                hasChange = true;
                mPreHeight = currHeight;
            } else {
                hasChange = false;
            }
        }
        if (hasChange) {
            boolean isShow;
            int keyboardHeight = 0;
            // 当当前的根视图高度和初始化时的高度一样时,说明此时软键盘没有显示,是消失状态
            if (mOriginHeight == currHeight) {
                //hidden
                isShow = false;
            } else {
                // 此时,根视图的高度减少了,而减少的部分就是软键盘的高度,软键盘显示状态
                //show
                keyboardHeight = mOriginHeight - currHeight;
                isShow = true;
            }

            if (mKeyBoardListen != null) {
                mKeyBoardListen.onKeyboardChange(isShow, keyboardHeight);
            }
        }
    }

    public void setKeyBoardListener(KeyBoardListener keyBoardListen) {
        this.mKeyBoardListen = keyBoardListen;
    }

    // 资源释放
    public void destroy() {
        if (mContentView != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                mContentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        }
    }

    public interface KeyBoardListener {

        void onKeyboardChange(boolean isShow, int keyboardHeight);
    }
}

以上便是实现软件盘显示和消失的监听,然后我们看一下具体的调用(布局中我设置了一个EditText,用于调起软键盘):

public class MainActivity extends AppCompatActivity implements KeyboardChangeListener.KeyBoardListener {
    private static final String TAG = "MainActivity";
    private KeyboardChangeListener mKeyboardChangeListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mKeyboardChangeListener = new KeyboardChangeListener(this);
        mKeyboardChangeListener.setKeyBoardListener(this);
    }

    @Override
    public void onKeyboardChange(boolean isShow, int keyboardHeight) {
        Log.d(TAG, "onKeyboardChange() called with: " + "isShow = [" + isShow + "], keyboardHeight = [" + keyboardHeight + "]");
    }
}

下面是我在logcat中的log截图,实现了对软键盘显示和消失的监听,并且获取到当前软键盘的高度:

log.png
上一篇下一篇

猜你喜欢

热点阅读