android6.0之前,是不存在键盘高度获取的,不过我发现在6.0的Api中,InputMethodManager中存在获取键盘高度的方法,不过被google@hide了.
由于之前自己写的逻辑处理一直未写在Blog里,最近想了一下还是写一下比较好,毕竟害怕那一天弄丢了.
onLayoutChangeListener中的处理逻辑:,其主要是获取ViewRootImpl中的mPendingContentInsets,
private class SystemLayoutListener implements OnLayoutChangeListener {
private Rect mVisibleRect = new Rect();
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
int oldRight, int oldBottom) {
v.getWindowVisibleDisplayFrame(mVisibleRect);
mWindowLayoutInfor.mVisibleSize.setSize(mVisibleRect);
if (mVisibleRect.height() > 0) {
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT && (getWindow().getAttributes().flags
& WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) {
translucentHandle(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom);
} else {
solidHandle(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom);
}
}
}
private void translucentHandle(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
int oldRight, int oldBottom) {
Rect mPendingContentInsets = (Rect) Tools.getFieldObject(v.getParent(), "mPendingContentInsets");
Rect rect = new Rect(mPendingContentInsets);
rect.top = 0;
int oldW = mWindowLayoutInfor.mNavigationSize.width();
int oldH = mWindowLayoutInfor.mNavigationSize.height();
boolean requestLayout = false;
if (mWindowLayoutInfor.mNavigationSize.setSize(rect)) {
requestLayout |= onNavigationLayoutChanged(oldW, oldH, mWindowLayoutInfor.mNavigationSize.width(),
mWindowLayoutInfor.mNavigationSize.height());
}
oldW = mWindowLayoutInfor.mKeyboardSize.width();
oldH = mWindowLayoutInfor.mKeyboardSize.height();
int h = rect.height();
int w = rect.width();
if (mWindowLayoutInfor.mKeyboardSize.setSize(0, mVisibleRect.bottom, mWindowLayoutInfor.mRealSize.right - w,
mWindowLayoutInfor.mRealSize.bottom - h)) {
requestLayout |= onKeyboardLayoutChanged(oldW, oldH, mWindowLayoutInfor.mKeyboardSize.width(),
mWindowLayoutInfor.mKeyboardSize.height());
}
if (requestLayout) {
v.requestLayout();
v.invalidate();
}
}
private void solidHandle(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
int oldRight, int oldBottom) {
int vertical = mWindowLayoutInfor.mRealSize.bottom - bottom;
int horizontal = mWindowLayoutInfor.mRealSize.right - left;
int oldW = mWindowLayoutInfor.mNavigationSize.width();
int oldH = mWindowLayoutInfor.mNavigationSize.height();
boolean requestLayout = false;
if (mWindowLayoutInfor.mNavigationSize.setSize(0, 0, horizontal, vertical)) {
requestLayout |= onNavigationLayoutChanged(oldW, oldH, mWindowLayoutInfor.mNavigationSize.width(),
mWindowLayoutInfor.mNavigationSize.height());
}
oldW = mWindowLayoutInfor.mKeyboardSize.width();
oldH = mWindowLayoutInfor.mKeyboardSize.height();
if (mWindowLayoutInfor.mKeyboardSize.setSize(0, mWindowLayoutInfor.mVisibleSize.bottom, 0,
mWindowLayoutInfor.mRealSize.bottom - vertical)) {
requestLayout |= onKeyboardLayoutChanged(oldW, oldH, mWindowLayoutInfor.mKeyboardSize.width(),
mWindowLayoutInfor.mKeyboardSize.height());
}
if (requestLayout) {
v.requestLayout();
v.invalidate();
}
}
}