Android监听软键盘弹出并获取软键盘高度

2017/6/16 16:40:01 人评论 次浏览 分类:TextView

前言

我们都知道在Android上软键盘弹出会使我们的窗口高度被压缩,这时我们可能就要通知界面做出调整以适应新的高度。
网上有很多监听软键盘弹出的方法,但大多用法过于复杂或存在缺陷,因此今天我们来聊聊如何简单的监听软键盘弹出并获取软键盘高度。

思路

上面已经提到了,软键盘弹出后APP窗口的高度会发生改变,而高度改变必然会导致View的onMeasure方法被调用,因此我们可以从这里下手。
我们可以自定义一个View继承自FrameLayout,作为我们要监听软键盘弹出的界面的容器,然后复写onMeasure方法。我们知道在onMeasure方法中,super.onMeasure调用之前,新的高度是不会被应用的,因此我们可以在super.onMeasure之前得到新的高度和旧的高度,以此判断键盘是否弹出。
这里还有一个问题,并不是只有软键盘弹出或隐藏会引起窗口高度改变,在一些支持隐藏导航栏(虚拟按键)的手机(比如很多华为手机)上,隐藏或弹出导航栏同样会引起窗口高度改变,我们也要加以判断。

实现

public class ResizeFrameLayout extends FrameLayout {
    private IKeyboardEvent mListener;
    private int navBarHeight;

    public interface IKeyboardEvent {
        void onKeyboardShown(int keyboardHeight);

        void onKeyboardHidden();
    }

    public ResizeFrameLayout(Context context) {
        super(context);
        navBarHeight = getNavBarHeight();
    }

    public ResizeFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        navBarHeight = getNavBarHeight();
    }

    public ResizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        navBarHeight = getNavBarHeight();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ResizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setKeyboardListener(IKeyboardEvent listener) {
        mListener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
        final int actualHeight = getHeight();

        if (actualHeight - proposedHeight > navBarHeight) {
            // 软键盘弹出(非导航栏弹出)
            int keyboardHeight = actualHeight - proposedHeight;
            notifyKeyboardEvent(true, keyboardHeight);
        } else if (proposedHeight - actualHeight > navBarHeight) {
            // 软键盘隐藏(非导航栏隐藏)
            notifyKeyboardEvent(false, 0);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private void notifyKeyboardEvent(boolean show, int keyboardHeight) {
        if (mListener == null) {
            return;
        }
        if (show) {
            mListener.onKeyboardShown(keyboardHeight);
        } else {
            mListener.onKeyboardHidden();
        }
    }

    private int getNavBarHeight() {
        Resources resources = getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return resources.getDimensionPixelSize(resourceId);
        }
        return 0;
    }
}

使用

将该View作为需要监听软键盘弹出隐藏的界面的容器,然后对该View添加监听器即可。

分享到: 腾讯 新浪 人人网 邮件 收藏夹 复制网址 更多

上一篇:使用Android Studio发布Android library到jCenter实战

下一篇:Android Studio使用Gradle导出包含assets文件夹的Jar包

相关教程


共有访客发表了评论 网友评论

验证码: 看不清楚?