Android 實現沉浸式狀態列
上一篇文章將Android 實現變色狀態列我們實現了變色的狀態列,也介紹了沉浸式狀態列和透明狀態列的區別,這篇文章我們實現沉浸式狀態列。
沉浸式狀態列的來源就是很多手機用的是實體按鍵,沒有虛擬鍵,於是開了沉浸模式就只有狀態列消失了。於是沉浸模式成了沉浸式狀態列。
我們先來看下具體的效果
開啟沉浸模式後,狀態列消失,從頂部向下滑動,狀態列出現,退出沉浸模式,狀態列也出現了。
我們的程式碼基於前一篇文章。首先是兩個開啟沉浸模式和關閉沉浸模式的函式
@SuppressLint("NewApi")
public static void hideSystemUI(View view) {
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
@SuppressLint ("NewApi")
public static void showSystemUI(View view) {
view.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
這些程式碼可以在google的開發者文件中找到,可以看這裡Using Immersive Full-Screen Mode
此外還需要一個輔助函式,用於獲得狀態列高度,使用反射獲得。
/**
* 獲狀態列高度
*
* @param context 上下文
* @return 通知欄高度
*/
public int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen" );
Object obj = clazz.newInstance();
Field field = clazz.getField("status_bar_height");
int temp = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(temp);
} catch (Exception e) {
e.printStackTrace();
}
return statusBarHeight;
}
點選hide按鈕進入沉浸模式,也就是隱藏狀態列,隱藏狀態列的同時我們需要修改Toolbar的上內邊距,否則會顯得很難看,這裡註冊一個監聽OnSystemUiVisibilityChangeListener,當進入沉浸模式後我們改變Toolbar的上內邊距
hide.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View view = getWindow().getDecorView();
hideSystemUI(view);
mToolbar.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
mToolbar.setPadding(mToolbar.getPaddingLeft(), 0,mToolbar.getPaddingRight(), mToolbar.getPaddingBottom());
}
});
}
});
進入沉浸模式後,手指從螢幕頂部向下劃,狀態列就出現了,過2秒左右它又會自動消失。
點選show按鈕退出沉浸模式,同時Toolbar的內邊距也要增加到狀態列的高度。
show.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View view = getWindow().getDecorView();
showSystemUI(view);
mToolbar.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
mToolbar.setPadding(mToolbar.getPaddingLeft(), getStatusBarHeight(MainActivity.this),mToolbar.getPaddingRight(), mToolbar.getPaddingBottom());
}
});
}
});
具體效果見上方的效果圖。
如果使用的是SystemBarTintManager這個類進行的狀態列的著色,除上方的操作外,還要在對應的監聽裡增加狀態列著色的禁止和啟動的功能。
進入沉浸模式,要禁用
tintManager.setStatusBarTintEnabled(false);
退出沉浸模式,要啟動
tintManager.setStatusBarTintEnabled(true);
如果你想更加平滑,則可以對padding的改成增加動畫,具體動畫效果自行新增。
切記在使用沉浸模式前記得判斷Android的版本。SYSTEM_UI_FLAG_IMMERSIVE_STICKY只能在大於等於API Level 19使用。你要相容低版本的同時使用沉浸模式。在使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY之前先用android.os.Build.VERSION.SDK_INT來判斷當前的系統版本是否是android4.4以上,如果是就啟用程式碼,如果不是則跳過不執行。