前言
一般手機的界面上都會有:狀態(tài)欄、標題欄、導(dǎo)航欄等固定的布局;
樣式圖
區(qū)別
-
沉浸式狀態(tài)欄:這種樣式其實就是把狀態(tài)欄、標題欄、導(dǎo)航欄都去掉,讓整個屏幕都只顯示應(yīng)用要顯示的界面,從而給用戶一種“沉浸”在里面的感覺!
效果圖1
效果圖2 -
透明狀態(tài)欄:這種樣式其實就是把狀態(tài)欄和標題欄配置成一種顏色,達到一種美觀效果!
效果圖
透明狀態(tài)欄
4.4版本一下沒辦法配置透明欄,4.4、5.0、6.0不同版本又會有不同的效果,所以我們要做好適配工作
實現(xiàn)步驟
- 去掉系統(tǒng)自帶的標題欄,采用自定義的狀態(tài)欄(自定義狀態(tài)欄推薦使用Toolbar)
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
- 設(shè)置狀態(tài)欄為透明
- 第一種方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
super.onCreate(savedInstanceState);
}
- 第二種方法:
使用android:windowTranslucentStatus屬性需要在res目錄下新建values-v19文件夾,style文件要放在里面。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
- 防止狀態(tài)欄和自定義標題欄重合
- 第一種方法:
在Activity的根布局文件中添加
- 第一種方法:
android:fitsSystemWindows="true"
```
- 第二種方法:
給在Toolbar的上方添加一個和狀態(tài)欄高度一樣的Veiw,并將這個View的背景色設(shè)置成和Toolbar的背景色一樣。也可以直接給Toobar設(shè)置paddingTop等于狀態(tài)欄高。
public static void setToolBarPaddingHeight(Window window, View view) {
//TODO: 代碼設(shè)置標題欄paddingtop為狀態(tài)欄的高
int statusBarHeight = getStatusBarHeight(window.getContext());
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());
}
public static int getStatusBarHeight(Context context) {
//TODO: 算取狀態(tài)欄的高
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
通過以上就可以實現(xiàn)透明狀態(tài)欄了。總的來說還是比較簡單的,下面貼一下只用代碼就可以實現(xiàn)透明狀態(tài)欄的工具類!
/**
* Created by ML on 2017/3/9.
* 前言:
* 在Android4.4之前,我們的應(yīng)用沒法改變手機的狀態(tài)欄顏色,google在Android4.4以后提供了設(shè)置狀態(tài)欄的方法;
* 沉浸式狀態(tài)欄和透明式狀態(tài)欄是不同的概念;
*/
public class UIUtils {
//TODO: 透明狀態(tài)欄相關(guān)方法
/**
* 相關(guān)Flag
WindowManager.LayoutParams.FLAG_FULLSCREEN
隱藏狀態(tài)欄
View.SYSTEM_UI_FLAG_VISIBLE API 14
默認標記
View.SYSTEM_UI_FLAG_LOW_PROFILE API 14
低調(diào)模式, 會隱藏不重要的狀態(tài)欄圖標
View.SYSTEM_UI_FLAG_LAYOUT_STABLE API 16
保持整個View穩(wěn)定, 常和控制System UI懸浮, 隱藏的Flags共用, 使View不會因為System UI的變化而重新layout
View.SYSTEM_UI_FLAG_FULLSCREEN API 16
狀態(tài)欄隱藏,效果同設(shè)置WindowManager.LayoutParams.FLAG_FULLSCREEN
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN API 16
視圖延伸至狀態(tài)欄區(qū)域,狀態(tài)欄上浮于視圖之上
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION API 14
隱藏導(dǎo)航欄
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION API 16
視圖延伸至導(dǎo)航欄區(qū)域,導(dǎo)航欄上浮于視圖之上
View.SYSTEM_UI_FLAG_IMMERSIVE API 19
沉浸模式, 隱藏狀態(tài)欄和導(dǎo)航欄, 并且在第一次會彈泡提醒, 并且在狀態(tài)欄區(qū)域滑動可以呼出狀態(tài)欄(這樣會系統(tǒng)會清楚之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標志)。使之生效,需要和View.SYSTEM_UI_FLAG_FULLSCREEN,View.SYSTEM_UI_FLAG_HIDE_NAVIGATION中的一個或兩個同時設(shè)置。
View.SYSTEM_UI_FLAG_IMMERSIVE_STIKY API 19
與上面唯一的區(qū)別是, 呼出隱藏的狀態(tài)欄后不會清除之前設(shè)置的View.SYSTEM_UI_FLAG_FULLSCREEN或View.SYSTEM_UI_FLAG_HIDE_NAVIGATION標志,在一段時間后將再次隱藏系統(tǒng)欄)
*/
/**
* 實現(xiàn)透明狀態(tài)欄且不需要配置android:fitsSystemWindows="true"
* 注意::標題欄根布局高度必須是自適應(yīng)
*
* @param window
* @param view 標題欄根布局(根布局高度必須是自適應(yīng))
*/
public static void setScreenTranslucentStatus(Window window, int Color, View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setTranslucentStatusForSDK_LOLLIPOP(window, Color);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatusForSDK_KITKAT(window);
}
setToolBarPaddingHeight(window, view);
}
/**
* 實現(xiàn)透明狀態(tài)欄需要配置android:fitsSystemWindows="true"
* 注意::標題欄根布局高度必須是自適應(yīng)
*
* @param window
*/
public static void setTranslucentStatusXML(Window window, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setTranslucentStatusForSDK_LOLLIPOP(window, color);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatusForSDK_KITKAT(window);
}
}
/**
* 設(shè)置Android狀態(tài)欄的字體顏色,狀態(tài)欄為亮色的時候字體和圖標是黑色,狀態(tài)欄為暗色的時候字體和圖標為白色
*
* @param dark 狀態(tài)欄字體和圖標是否為深色
*/
public static void setStatusBarFontDark(@NonNull Window window, @NonNull boolean dark, int color, View view) {
//TODO: 實現(xiàn)狀態(tài)欄白底黑字
if (PhoneUtil.isMIUI()) {
setMIUIBarFontDark(window, dark, view);
} else if (PhoneUtil.isFlyme()) {
setFlymeBarFontDark(window, dark, view);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setSDK_MBarFontDark(window, dark, view);
} else {
L.i("Android原生6.0一下系統(tǒng)>>>>>>>>>>>>>>>實現(xiàn)狀態(tài)欄灰底白字");
setToolBarBgColor(window, color, view);
}
}
public static void setSDK_MBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
//TODO: 配置Android原生6.0系統(tǒng)狀態(tài)欄白底黑字
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (dark) {
setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
window.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
L.i("Android原生6.0系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
}
}
}
public static void setFlymeBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
//TODO: 配置魅族系統(tǒng)狀態(tài)欄白底黑字
try {
setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
WindowManager.LayoutParams lp = window.getAttributes();
Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
L.i("小米系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setMIUIBarFontDark(@NonNull Window window, @NonNull boolean dark, View view) {
//TODO: 配置小米系統(tǒng)狀態(tài)欄白底黑字
try {
setScreenTranslucentStatus(window, Color.TRANSPARENT, view);
Class clazz = window.getClass();
Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
int darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) { //狀態(tài)欄亮色且黑色字體
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
} else { //清除黑色字體
extraFlagField.invoke(window, 0, darkModeFlag);
}
L.i("小米系統(tǒng)>>>>>>>>>>>>>>>狀態(tài)欄白底黑字");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setToolBarBgColor(Window window, int color, View view) {
//TODO: Android原生5.0一下系統(tǒng)實現(xiàn)灰底白字
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setTranslucentStatusForSDK_LOLLIPOP(window, color);
setToolBarPaddingHeight(window, view);
} else {
// setTranslucentStatusForSDK_KITKAT(window);
L.i("Android原生4.4以上5.0一下系統(tǒng)需要自己手動在狀態(tài)欄加view實現(xiàn)灰底白字(http://www.lxweimin.com/p/a44c119d6ef7)");
}
}
public static void setToolBarPaddingHeight(Window window, View view) {
//TODO: 代碼設(shè)置標題欄paddingtop為狀態(tài)欄的高
int statusBarHeight = getStatusBarHeight(window.getContext());
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());
}
public static void setTranslucentStatusForSDK_KITKAT(Window window) {
//TODO: 4.4以上系統(tǒng)狀態(tài)欄透明
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
public static void setTranslucentStatusForSDK_LOLLIPOP(Window window, int Color) {
//TODO: 5.0以上系統(tǒng)狀態(tài)欄透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color); //TODO: 指定狀態(tài)欄的顏色和布局的顏色相同
}
}
public static int getStatusBarHeight(Context context) {
//TODO: 算取狀態(tài)欄的高
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
```
#### 沉浸式狀態(tài)欄
重寫Activity的onWindowFocusChanged()方法,然后加入如下邏輯即可:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.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);
}
}
[參考文章1](http://blog.csdn.net/xuchao_blog/article/details/54693482)
[參考文章2](http://www.lxweimin.com/p/a44c119d6ef7)