android页面布局中,底部的布局被键盘顶起连环问题解决

1. 先说下遇到的几种情况

(1)activity的布局
ps:为了保密,页面不能贴出来,但是也不想写个demo了,那么就展示我拙劣的画图技术吧
在这里插入图片描述
线性布局使用的android:layout_alignParentBottom="true"这个属性

(2)activity的配置

android:windowSoftInputMode="stateAlwaysHidden|adjustResize"

很完美的一个页面,但是当键盘弹起的时候,底部的按钮布局被键盘顶起,就变成了这样,会挡住scrollView中的输入框
在这里插入图片描述
(3)查找方法,把activity的配置改成这样

android:windowSoftInputMode="adjustPan|stateHidden"

这下绿色的底部局消停了,乖乖的呆在下面了,但是当scrollView的内容超出屏幕高度时候,新的问题出现了。
在这里插入图片描述
图片可能表达的不太清楚,我解释下,这种情况就是键盘把整个布局顶出去了,没错,标题栏也出去了,话说这个布局还真是直,掰弯很难。
试了剩下的几种|adjustUnspecified|adjustNothing,效果大同小异,看来这条路是走不通了,也试着把主布局换成线性,效果一样,看来和布局没关系。

2.解决方式1(在有些有手机上无效)

后来想到了,监听键盘的弹出和隐藏,然后动态的设置底部局高度来解决。
activity用这种配置

android:windowSoftInputMode="stateAlwaysHidden|adjustResize"

然后,用以下代码来监听键盘的弹出和隐藏状态

RelativeLayout rootView = findViewById(R.id.root_view);
rootView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        if (bottom - oldBottom < -1) {
            //软键盘弹出
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                    0);//动态设置高度为0
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            llBottomBtn.setLayoutParams(params);
        } else if (bottom - oldBottom > 1) {
            //软键盘隐藏
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                    (int) MeasureUtil.dp2px(mContext, 46));//动态设置高度,恢复原先控件高度
            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            llBottomBtn.setLayoutParams(params);
        }
    }
});

很开心的解决了,但是在android 9.0的华为手机上测试的时候,又有问题了。断点调试发现bottom - oldBottom == 0。

3.解决方式2

于是就找了另一种键盘监听的方式

 final View decorView = activity.getWindow().getDecorView();
 decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
         Rect rect = new Rect();
         //获取窗体的可视区域
         decorView.getWindowVisibleDisplayFrame(rect);
         //获取不可视区域高度,
         //在键盘没有弹起时,main.getRootView().getHeight()调节度应该和rect.bottom高度一样
         int mainInvisibleHeight = decorView.getRootView().getHeight() - rect.bottom;
         int screenHeight = decorView.getRootView().getHeight();//屏幕高度
         //不可见区域大于屏幕本身高度的1/4
         if (mainInvisibleHeight > screenHeight / 4) {键盘弹起了
             if (llBottomBtn.getHeight() != 0) {//因为onGlobalLayout方法会频繁回调,这里要判断下,不重复设置
                 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                         0);
                 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                 llBottomBtn.setLayoutParams(params);
             }
         } else {
             if (llBottomBtn.getHeight() == 0) {//因为onGlobalLayout方法会频繁回调,这里要判断下,不重复设置
                 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                         (int) MeasureUtil.dp2px(mContext, 46));
                 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                 llBottomBtn.setLayoutParams(params);
             }
         }
     }
 });

测试了几台手机,没有问题,到此问题解决!
呼,松一口气,致敬这个问题解决,迎接下个问题的到来。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐