文章说明:本文章核心解决方案来自这里 戳我戳我 ,本文章主要对原方法的小修改,以及使用时遇到的一些问题的解决分享。
/**
* 布局在输入法之上
*
* @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" />
如果我的文章帮到了你,请。。麻烦。。多谢!