專案中我們有時候都要用的透明狀態列(這裡也成沉浸式狀態列),今天介紹一個gyf-dev寫的一個封裝狀態列開源框架
效果圖如下:
正文
從Android4.4開始,才可以實現狀態列著色,並且從5.0開始系統更加完善了這一功能。之前寫過關於一篇 關於activity狀態列的一些總結
有關Activity樣式 、狀態列透明、螢幕亮度問題應用場景及其總結
說明
-
第一種方案: 可直接在主題中設定
getWindow().setBackgroundDrawable(null); //設定透明狀態列 ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT); View parentView = contentFrameLayout.getChildAt(0); if (parentView != null && Build.VERSION.SDK_INT >= 14) { parentView.setFitsSystemWindows(true); }複製程式碼
或者也可以這樣 :
-
第二種方案:
將佈局延伸到狀態列來處理,這次我們使用android:fitsSystemWindows=”true”屬性,不讓佈局延伸到狀態列,這時狀態列就是透明的,然後新增一個和狀態列高、寬相同的指定顏色View來覆蓋被透明化的狀態列。我們一步步來實現。
1、第一步還是先將狀態列透明化,方法同上。
2、在佈局檔案中新增android:fitsSystemWindows=”true”屬性:
封裝:
ImmersionBar.with(this)
.transparentStatusBar() //透明狀態列,不寫預設透明色
.transparentNavigationBar() //透明導航欄,不寫預設黑色(設定此方法,fullScreen()方法自動為true)
.transparentBar() //透明狀態列和導航欄,不寫預設狀態列為透明色,導航欄為黑色(設定此方法,fullScreen()方法自動為true)
.statusBarColor(R.color.colorPrimary) //狀態列顏色,不寫預設透明色
.navigationBarColor(R.color.colorPrimary) //導航欄顏色,不寫預設黑色
.barColor(R.color.colorPrimary) //同時自定義狀態列和導航欄顏色,不寫預設狀態列為透明色,導航欄為黑色
.statusBarAlpha(0.3f) //狀態列透明度,不寫預設0.0f
.navigationBarAlpha(0.4f) //導航欄透明度,不寫預設0.0F
.barAlpha(0.3f) //狀態列和導航欄透明度,不寫預設0.0f
.statusBarDarkFont(true) //狀態列字型是深色,不寫預設為亮色
.flymeOSStatusBarFontColor(R.color.btn3) //修改flyme OS狀態列字型顏色
.fullScreen(true) //有導航欄的情況下,activity全屏顯示,也就是activity最下面被導航欄覆蓋,不寫預設非全屏
.hideBar(BarHide.FLAG_HIDE_BAR) //隱藏狀態列或導航欄或兩者,不寫預設不隱藏
.addViewSupportTransformColor(toolbar) //設定支援view變色,可以新增多個view,不指定顏色,預設和狀態列同色,還有兩個過載方法
.titleBar(view) //解決狀態列和佈局重疊問題,任選其一
.statusBarView(view) //解決狀態列和佈局重疊問題,任選其一
.fitsSystemWindows(true) //解決狀態列和佈局重疊問題,任選其一,預設為false,當為true時一定要指定statusBarColor(),不然狀態列為透明色
.supportActionBar(true) //支援ActionBar使用
.statusBarColorTransform(R.color.orange) //狀態列變色後的顏色
.navigationBarColorTransform(R.color.orange) //導航欄變色後的顏色
.barColorTransform(R.color.orange) //狀態列和導航欄變色後的顏色
.removeSupportView(toolbar) //移除指定view支援
.removeSupportAllView() //移除全部view支援
.navigationBarEnable(true) //是否可以修改導航欄顏色,預設為true
.navigationBarWithKitkatEnable(true) //是否可以修改安卓4.4和emui3.1手機導航欄顏色,預設為true
.fixMarginAtBottom(true) //當xml裡使用android:fitsSystemWindows="true"屬性時,解決4.4和emui3.1手機底部有時會出現多餘空白的問題,預設為false,非必須
.addTag("tag") //給以上設定的引數打標記
.getTag("tag") //根據tag獲得沉浸式引數
.reset() //重置所以沉浸式引數
.keyboardEnable(true) //解決軟鍵盤與底部輸入框衝突問題,預設為false,還有一個過載方法,可以指定軟鍵盤mode
.init(); //必須呼叫方可沉浸式複製程式碼
使用方式
- 第一步:基礎用法(已經可以滿足日常沉浸式)
ImmersionBar.with(this).init();複製程式碼
- 第二步
在activity的onDestroy方法中執行
ImmersionBar.with(this).destroy(); //不呼叫該方法,如果介面bar發生改變,在不關閉app的情況下,退出此介面再進入將記憶最後一次bar改變的狀態複製程式碼
-
建議
建議在BaseActivity中初始化和銷燬,可以參看demo中
BaseActivitypublic class BaseActivity extends AppCompatActivity { private ImmersionBar mImmersionBar; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mImmersionBar = ImmersionBar.with(this); mImmersionBar.init(); //所有子類都將繼承這些相同的屬性 } @Override protected void onDestroy() { super.onDestroy(); mImmersionBar.destroy(); //不呼叫該方法,如果介面bar發生改變,在不關閉app的情況下,退出此介面再進入將記憶最後一次bar改變的狀態 } }複製程式碼
- 如何 隱藏導航欄或狀態列
/** * 隱藏導航欄或狀態列 * * @param barHide the bar hide * @return the immersion bar */ public ImmersionBar hideBar(BarHide barHide) { mBarParams.barHide = barHide; if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT || OSUtils.isEMUI3_1()) { if ((mBarParams.barHide == BarHide.FLAG_HIDE_NAVIGATION_BAR) || (mBarParams.barHide == BarHide.FLAG_HIDE_BAR)) { mBarParams.navigationBarColor = Color.TRANSPARENT; mBarParams.fullScreenTemp = true; } else { mBarParams.navigationBarColor = mBarParams.navigationBarColorTemp; mBarParams.fullScreenTemp = false; } } return this; }複製程式碼
部分問題
解決華為emui3.0或者3.1手機手動隱藏導航欄按鈕時,導航欄背景未被隱藏的問題
第一種解決方案,監聽華為虛擬按鈕,建議在baseActivity裡使用
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
immersionBar = ImmersionBar.with(this);
immersionBar.init();
if (OSUtils.isEMUI3_1()) //解決華為emui3.0與3.1手機手動隱藏底部導航欄時,導航欄背景色未被隱藏的問題
getContentResolver().registerContentObserver(Settings.System.getUriFor
("navigationbar_is_min"), true, mNavigationStatusObserver);
}
private ContentObserver mNavigationStatusObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
int navigationBarIsMin = Settings.System.getInt(getContentResolver(),
"navigationbar_is_min", 0);
if (navigationBarIsMin == 1) {
//導航鍵隱藏了
immersionBar
.transparentNavigationBar()
.init();
} else {
//導航鍵顯示了
immersionBar
.navigationBarColor(android.R.color.black)
.fullScreen(false)
.init();
}
}
};複製程式碼
- 第二種解決方案,禁止對導航欄相關設定
ImmersionBar.with(this) .navigationBarEnable(false) //禁止對導航欄相關設定 //或者 // .navigationBarWithKitkatEnable(false) //禁止對4.4裝置導航欄相關設定 .init();複製程式碼
android 6.0 有導航欄效果
專案地址:
gyf-dev的部落格地址:
部落格地址:
如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部