android 软键盘显隐


前言

最近遇到软键盘的显隐判断问题,原来也遇过一次,所以这次针对这类问题的解决方法做下记录,也希望帮助后面碰到相同问题的你们。

根据自己的经验,这里有三种解决方法,其实原理都是一样的。我们都知道软件盘的弹出,视图的布局会发生改变,所以可以通过布局的改变来判断是否显示了软件盘。

自定义方法

个人觉得它的灵活性相对于别的更高。因为这只是在类中定义一个方法,来判断是否软键盘触发了。这样你可以运用到任何监听事件中来获取软件盘的状态。示例代码如下:

判断状态:

private boolean isKeyboardShown(View rootView) {
        final int softKeyboardHeight = 100;
        Rect r = new Rect();
        // 获取根布局的可视区域r
        rootView.getWindowVisibleDisplayFrame(r);
        DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
        // 本来的实际底部距离 - 可视的底部距离
        int heightDiff = rootView.getBottom() - r.bottom;
        return heightDiff > softKeyboardHeight * dm.density;
    }

例如在onTouch中判断:

@Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN && isKeyboardShown(chatContent.getRootView()))
            manager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        return false;
    }

调用Android API

其实查阅API发现Android已经帮我们实现了布局改变的监听的类,我们可以使用addOnGlobalLayoutListener来监听整个布局的状态。这个监听器在我们的布局发生改变时会调用onGlobalLayout方法,所以我们可以在其中进行操作。当然在使用该监听时要先获取整个视图树的观察者。

final View root = findViewById(R.id.main);
        ViewTreeObserver observer = root.getViewTreeObserver();

再添加监听:

observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int heightDiff = root.getRootView().getHeight() - root.getHeight();
                if (heightDiff > 100){ //一般超过100视为弹出
                    //显示操作
                }else{
                    //隐藏操作
                }
            }
        });

自定义外部类

其实使用该方法就是自定义一个布局继承Android基本布局控件,然后在其中重写onMeasure方法,在该方法中的操作与前面的基本类似。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity) getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff > 100);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

这里自定义与实现了监听接口

public interface Listener {
        void onSoftKeyboardShown(boolean isShowing);
    }

    private Listener listener;

    public void setListener(Listener listener) {
        this.listener = listener;
    }

最后在xml中使用该自定义布局,目标类中绑定调用:

RelativeLayoutThatDetectsSoftKeyboard chatLayout = (RelativeLayoutThatDetectsSoftKeyboard) findViewById(R.id.chat_bottm);
        chatLayout.setListener(this);                
@Override
    public void onSoftKeyboardShown(boolean isShowing) {
        if (isShowing)
            //显示操作
    }

这个的好处就是逻辑对外封装、解耦了,只要根据isShowing的值进行操作。

好了,我只是大自然的搬运工,到底要用哪种就自己视情况而定吧

欢迎访问:http://idisfkj.github.io/archives/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值