Android 输入法将底部布局顶上去遮挡布局问题
最近在项目中遇到使用ReletiveLayout将View固定在底部,但弹出输入框时底部的View被顶上去的问题, 尝试了很多解决办法 ,如下:
方法一:在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
方法二:在项目的AndroidManifest.xml文件中界面对应的<activity>里加入android:windowSoftInputMode="stateVisible|adjustResize",这样会让屏幕整体上移。如果加上的是
android:windowSoftInputMode="adjustPan"这样键盘就会覆盖屏幕。
方法三:把顶级的layout替换成ScrollView,或者说在顶级的Layout上面再加一层ScrollView的封装。这样就会把软键盘和输入框一起滚动了,软键盘会一直处于底部。
方法四:更换根布局
方法五:在根布局下加上fitsSystemwindows = true
尝试后发现:
方法一无效(ReletiveLayout下设置属性无效)
方法二无效(ReletiveLayout下设置属性无效)
方法三有效,但不适合 (布局没有超过屏幕,使用ScroollView使得View都挨在一起,只能通过magin值控制距离,不准确)
方法四无效
方法五无效
试过这么多都没用,真没办法了,最后只能监听软键盘的显示和隐藏来控制 底部布局的显隐,这样可以解决问题,不过有点闪动,问题不是很大。
照搬的代码,监听代码如下 :
public class KeyboardStateObserver {
private static final String TAG = KeyboardStateObserver.class.getSimpleName();
public static KeyboardStateObserver getKeyboardStateObserver(Activity activity) {
return new KeyboardStateObserver(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private OnKeyboardVisibilityListener listener;
public void setKeyboardVisibilityListener(OnKeyboardVisibilityListener listener) {
this.listener = listener;
}
private KeyboardStateObserver(Activity activity) {
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
if (listener != null) {
listener.onKeyboardShow();
}
} else {
if (listener != null) {
listener.onKeyboardHide();
}
}
usableHeightPrevious = usableHeightNow;
Log.d(TAG,"usableHeightNow: " + usableHeightNow + " | usableHeightSansKeyboard:" + usableHeightSansKeyboard + " | heightDifference:" + heightDifference);
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
Log.d(TAG,"rec bottom>" + r.bottom + " | rec top>" + r.top);
return (r.bottom - r.top);// 全屏模式下: return r.bottom
}
public interface OnKeyboardVisibilityListener {
void onKeyboardShow();
void onKeyboardHide();
}
}
在界面中使用:
KeyboardStateObserver.getKeyboardStateObserver(this).
setKeyboardVisibilityListener(new KeyboardStateObserver.OnKeyboardVisibilityListener() {
@Override
public void onKeyboardShow() {
Toast.makeText(MainActivity.this,"键盘弹出",Toast.LENGTH_SHORT).show();
}
@Override
public void onKeyboardHide() {
Toast.makeText(MainActivity.this,"键盘收回",Toast.LENGTH_SHORT).show();
}
});