Android 解决输入法遮挡布局控件的问题

本文介绍了如何解决Android应用中输入法弹出时遮挡布局控件的问题,特别是针对ScrollView的情况进行了优化处理,并提供了在Fragment中处理此问题的建议,通过调整Activity的android:windowSoftInputMode属性。

                文章说明:本文章核心解决方案来自这里 戳我戳我   ,本文章主要对原方法的小修改,以及使用时遇到的一些问题的解决分享。

               

   /**
     * 布局在输入法之上
     *
     * @param root    最外层布局,需要调整的布局
     * @param btmView 最底部的控件
     */
    public static ViewTreeObserver.OnGlobalLayoutListener getKeyboardListener(final View root, final View btmView) {
       return new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                //获取root在窗体的可视区域
                root.getRootView().getWindowVisibleDisplayFrame(rect);
                //获取root在窗体的不可视区域高度(被其他View遮挡的区域高度)
                int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;
                //若不可视区域高度大于 h/4,则键盘显示
                if (rootInvisibleHeight > root.getRootView().getHeight() / 4) {
                    int[] location;
                    if (btmView.getTag() == null) {
                        location = new int[2];
                        //获取scrollToView在窗体的坐标
                        btmView.getLocationInWindow(location);
                        btmView.setTag(location);
                    } else {
                        location = (int[]) btmView.getTag();
                    }

                    //计算root滚动高度,使scrollToView在可见区域
                    final int srollHeight = (location[1] + btmView.getHeight()) - rect.bottom;
                    if (srollHeight != 0) {
                        root.scrollTo(0, srollHeight);
                            if (root instanceof ScrollView) {
                                root.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        ((ScrollView) root).fullScroll(View.FOCUS_DOWN);
                                    }
                                });
                            }
                    }
                } else {
                    //键盘隐藏
                    root.scrollTo(0, 0);
                }
            }
        };
    }

    //移除布局监听
    public static void removeGlobalLayoutListener(View root, ViewTreeObserver.OnGlobalLayoutListener listener) {
        if (root != null && listener != null) {
            //最低api 16
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                root.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
            } else {
                root.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
            }
        }
    }
   
    //使用方式 初始化时加入监听
    ViewTreeObserver.OnGlobalLayoutListener  mKeyboardListener = getKeyboardListener(root, btmView);
    root.getViewTreeObserver().addOnGlobalLayoutListener(mKeyboardListener);
 
    //退出的时候移除监听
    removeGlobalLayoutListener(root, mKeyboardListener);

        以上核心代码和 戳我 里面的基本一致,但也有点小区别,多了下面的操作:  

    if (root instanceof ScrollView) {
                        root.post(new Runnable() {
                            @Override
                            public void run() {
                                ((ScrollView) root).fullScroll(View.FOCUS_DOWN);
                            }
                        });
                    }

      当rootView 为  scrollview时,有些系统(可能是低版本系统),scrollview内的控件并不会一起往上移到,虽然scrollview已经在输入法上面了

  (被遮挡的控件可以通过滑动看到),但整体效果还是遮挡,所以以上的判断就是解决scrollview内控件被遮挡问题。

      以上的方法足以解决大部分Activity的主布局被输入法遮挡问题,当你用的是Fragment捆绑在Activity里面,如果只是简单调用这个监听方法,

   那就不一定得到你想要的效果了,必须为这个Activity设置输入法监听了,这里提供一个参考,在manifest里面对应的Activity设置    

   android:windowSoftInputMode 属性,如:

 <activity
            android:name=".XxxActivity"
            android:windowSoftInputMode="adjustPan" />

                      

                         如果我的文章帮到了你,请。。麻烦。。多谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值