沉浸式标题栏导致布局底部EditText弹出软键盘时引起edittext被覆盖或标题栏被弹出问题的终极解决方案

之前项目用到ImmersionBar,结果引起布局中edittext靠底部的页面软键盘弹出效果不适,在网上查阅各种回答,都是说一些修改mainfest之类的 如adjustResize,stateHidden,adjustPan,或者嵌套scrollview自动解决什么的,然后高高兴兴到项目上实践,然并没什么卵用。。。。。。一怒之下决定在根布局(不包含标题)用Scrollview嵌套布局,然后监听弹出软键盘后,计算软键盘的覆盖高度来手动滑动Scrollview来得到想要的效果。其实很简单,方案如下:

1.首先要监听弹出软键盘根布局的变化,这个用scrollview来监听

srollview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //todo 这里处理想要监听的edittext对象
        doscrollEvent(scrollview,lastLocation,et1,et2,et3);//et1,et2,et3为想要监听的edittext
    }
});

2.然后再回调方法中处理滑动逻辑

private void doScrollEvent(ScrollView sv,int[] lastLocation,EditText... ets){//ets为可能引起scrollview滑动的et
    Rect rect = new Rect();
    sv.getWindowVisibleDisplayFrame(rect);//获取当前sv的可见范围
    int invisibleHeight = sv.getHeight() - rect.bottom;//sv在屏幕上的总高度减去当前可见的底部位置即得到被覆盖高度
    int scrollY = sv.getScrollY();
    for(EditText et:ets){
        if(et.isFocused()){//首先判断当前et是否获取了焦点,只有获取了焦点才能弹出键盘
            if(invisibleHeight>100){//这个100随便取得表示scrollview被覆盖高度超过这个值是就是软键盘弹出了
                 int[] location = new int[2];
                 lastLocation[0] = scrollY;//滑动前记录已滑动位置
                 et.getLocationInWindow(location);
                 int height = et.getHeight();
                 if(location[1]+height>rect.bottom){//判断当前et是否被覆盖
                    sv.scrollBy(0,location[1]+height-rect.bottom);  //滑动sv使et刚好在键盘上方
                }        
            }else {//关软键盘后记得复原scrollview位置
                if(lastLocation[0]!=scrollY){//判断软键盘是否触发过scrollview滑动
                    sv.scrollTo(0,lastLocation[0]);//复原
                }
                lastLocation[0]=sv.getScrollY();//复原后记录新的滑动位置
            }
            break;
        }
    }
}

3.上面的lastLocation[0]是用于记录scrollview的滑动位置,初始值为{0},要在OnGlobalLayoutListener外面设置好,因为要用final修饰不可变,所以用数组。

最后记得把你mainfest和activity下设置的windowSoftInputMode都去掉

OK,在运行问题解决了!!!

你可能感兴趣的:(杂七杂八)