最近的項目中有用到設置狀態欄透明,也就是做沉浸式狀態欄,但是在實現的過程中也遇到了一些問題,所以在這裏做個總結,同時尋求更好的解決方案。網上設置沉浸式狀態欄的方式有好幾種,以下是我採用的方法:
@TargetApi(19)
public void transparencyBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
decorView.removeViewAt(decorView.getChildCount() - 1);
ViewGroup rootView = (ViewGroup)((ViewGroup)activity.findViewById(android.R.id.content)).getChildAt(0);
rootView.setFitsSystemWindows(false);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
rootView.requestLayout();
}
AndroidBug5497Workaround.assistActivity(this);
}
同時要在佈局文件裏設置根佈局android:fitsSystemWindows="false"。這種方式適合商城類詳情頁面,上面是圖片,整個是一個scrollview。
第一個問題就是如果佈局下方有edittext的話,當其獲得焦點的時候,佈局不會自動調整,有時會出現小鍵盤擋住edittext,用戶體驗不好。所以在上一段代碼的最後引入了AndroidBug5497Workaround這個類。關於這個類的源碼可查看:AndroidBug5497Workaround。引入後即可自動調整佈局。注意:最後一句代碼需與沉浸式狀態欄一起設置,不可單獨設置,否則自動調整的高度會有問題。
第二個問題是有的手機(例如華爲)底部會有虛擬按鍵,上述的代碼會使虛擬按鍵變成透明,並會擋住下面的佈局。這個時候可以將window.setNavigationBarColor(Color.TRANSPARENT);這句代碼註釋掉,虛擬按鍵就不會變色了。關於虛擬按鍵擋住佈局以及小鍵盤彈出時不調整佈局其實都是因爲android:fitsSystemWindows="false"引起的,但是改爲true呢又會使頂部狀態欄變回去。對於虛擬按鍵的問題,我選擇了判斷當前頁面是否有虛擬按鍵,如果有點話就給被擋住的佈局設置一個底部的padding,高度爲虛擬按鍵的高度,沒有虛擬按鍵的話就不處理。以下爲我採用的判斷是否有虛擬按鍵的代碼:
/**
* 判斷底部navigator是否已經顯示
* @param windowManager 當前activity的windowManager(getWindowManager)
* @return 是否有虛擬按鍵
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public boolean hasSoftKeys(WindowManager windowManager){
Display d = windowManager.getDefaultDisplay();
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
d.getRealMetrics(realDisplayMetrics);
int realHeight = realDisplayMetrics.heightPixels;
int realWidth = realDisplayMetrics.widthPixels;
DisplayMetrics displayMetrics = new DisplayMetrics();
d.getMetrics(displayMetrics);
int displayHeight = displayMetrics.heightPixels;
int displayWidth = displayMetrics.widthPixels;
bottomHeight = realHeight - displayHeight;
return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
}
其中bottomHeight就是虛擬按鍵的高度,可以存成常量並設置padding。這樣設置之後就可以適配有虛擬按鍵的機型了。對於這些問題可能有更好的解決方案,我的方案也是從網上獲取,希望能夠幫到掉到坑裏的同學。