之前项目用到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,在运行问题解决了!!!