背景
最近在給項(xiàng)目添加沉浸式狀態(tài)欄時(shí)遇到了一個(gè)很奇葩的問題,在Android4.4以上系統(tǒng)底部聊天及評(píng)論框不能被系統(tǒng)輸入法頂上去。如下圖1(圖片引用自另外兩種android沉浸式狀態(tài)欄實(shí)現(xiàn)思路,更詳細(xì)的問題描述也可進(jìn)入這個(gè)鏈接查看)。

圖1.png
原因是因?yàn)樵O(shè)置狀態(tài)欄透明后沒有設(shè)置android:fitsSystemWindows="true"這個(gè)屬性。我的解決辦法是使用AndroidBug5497Workaround 類動(dòng)態(tài)計(jì)算布局的高度。這個(gè)方法原始代碼在華為等手機(jī)上存在高度計(jì)算不準(zhǔn)確的兼容性問題。我在源碼的基礎(chǔ)上做了一些修改,目前在華為,小米,三星等手機(jī)上測(cè)試均正常,修改后的代碼如下。
public class AndroidBug5497Workaround {
public static void assistActivity(Activity activity) {
new AndroidBug5497Workaround(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private int contentHeight;
private boolean isfirst = true;
private Activity activity;
private int statusBarHeight;
private AndroidBug5497Workaround(Activity activity) {
//獲取狀態(tài)欄的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
this.activity = activity;
FrameLayout content = (FrameLayout)activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
//界面出現(xiàn)變動(dòng)都會(huì)調(diào)用這個(gè)監(jiān)聽事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (isfirst) {
contentHeight = mChildOfContent.getHeight();//兼容華為等機(jī)型
isfirst = false;
}
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams)
mChildOfContent.getLayoutParams();
}
//重新調(diào)整跟布局的高度
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
//當(dāng)前可見高度和上一次可見高度不一致 布局變動(dòng)
if (usableHeightNow != usableHeightPrevious) {
//int usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容華為等機(jī)型
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
//frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard -heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
/** * 計(jì)算mChildOfContent可見高度 ** @return */
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}
注意事項(xiàng):
使用這個(gè)方法有個(gè)限制是布局內(nèi)得包含有大小可調(diào)的布局如ListView,ScrollView等,并且最大高度(使用權(quán)重weight)至少得大于軟鍵盤和輸入框的高度之和。一般的聊天界面本身就是個(gè)ListView,所有不用擔(dān)心這個(gè)問題。
使用方法
在你的Activity的oncreate()方法里調(diào)用AndroidBug5497Workaround.assistActivity(this);即可。注意:在setContentView(R.layout.xxx)之后調(diào)用。
關(guān)于AndroidBug5497Workaround更詳細(xì)的介紹可以看這里android 軟鍵盤在全屏下的布局計(jì)算問題