1. 原生設(shè)置沉浸式狀態(tài)欄:
(1) 在底層activity中設(shè)置:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Android 5.0 以上 全透明
Window window = 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);
// 狀態(tài)欄(以上幾行代碼必須,參考setStatusBarColor|setNavigationBarColor方法源碼)
window.setStatusBarColor(Color.TRANSPARENT);
// 虛擬導(dǎo)航鍵
window.setNavigationBarColor(0xfff0f0f0);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Android 4.4 以上 半透明
Window window = getWindow();
// 狀態(tài)欄
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 虛擬導(dǎo)航鍵
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
(2) 設(shè)置閃屏頁(yè)全面屏隱藏狀態(tài)欄和虛擬按鍵
//取消狀態(tài)欄
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//一定得在setContentView()上面
//隱藏虛擬按鍵:
protected void hideBottomUIMenu() {
//隱藏虛擬按鍵,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
//這個(gè)也可以:
public void hideNavigationBar() {
int uiFlags = 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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN; // hide status bar
if (android.os.Build.VERSION.SDK_INT >= 19) {
uiFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE;//0x00001000; // SYSTEM_UI_FLAG_IMMERSIVE_STICKY: hide
} else {
uiFlags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
try {
getWindow().getDecorView().setSystemUiVisibility(uiFlags);
} catch (Exception e) {
// TODO: handle exception
}
}
(3) flutter中設(shè)置:
3.1在main.dart, build前中設(shè)置:
SystemUiOverlayStyle systemUiOverlayStyle =
SystemUiOverlayStyle(
statusBarColor: Colors.transparent,//狀態(tài)欄
systemNavigationBarColor:Color(0xfff0f0f0),//虛擬按鍵背景色
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.dark,//虛擬按鍵圖標(biāo)色
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.light,
);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
3.2若界面有AppBar
可以直接在AppBar中的 brightness設(shè)置狀態(tài)欄字體顏色,值如下
Brightness.light:黑色
Brightness.dark: 白色
AppBar中的brightness值若不設(shè)置,改值會(huì)默認(rèn)取全局的theme中設(shè)置primaryColorBrightness的值,
3.3若界面沒(méi)有AppBar
則同在main.dart中設(shè)置一樣在build中設(shè)置,(但是會(huì)有問(wèn)題),該界面狀態(tài)欄字體顏色會(huì)在進(jìn)入下一個(gè)頁(yè)面后回退時(shí),保持上個(gè)頁(yè)面的狀態(tài)欄樣顏色。所以建議可以設(shè)置一個(gè)沒(méi)有高度的AppBar,這樣就可以隨意設(shè)置狀態(tài)欄字體顏色:沒(méi)高度的AppBar如下:
PreferredSize(
child: AppBar(
backgroundColor: Colors.white,
elevation: 0,//appBar底部線去除
),
preferredSize: Size.fromHeight(0))
但是使用AppBar若界面是圖片置頂?shù)模瑒t不能做到沉浸式。所以使用3.3的方式(暫時(shí)沒(méi)有找到更好的方法)
(4)在flutter中使用flutter_boost
需要在native端設(shè)置相應(yīng)通過(guò)flutter_boost跳轉(zhuǎn)的頁(yè)面,flutter的頁(yè)面也需要單獨(dú)設(shè)置。
4 配上兼容部分機(jī)型的代碼
使用
//狀態(tài)欄
StatusBarUtils.setLightStatusBar(this,true);
//虛擬按鍵背景
StatusBarUtils.setStatusBarColor(this, 0xff666666);
package com.paff.myapplication.utils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class StatusBarUtils {
@TargetApi(19)
public static void transparencyBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 修改狀態(tài)欄顏色,支持4.4以上版本
*
* @param activity
* @param color
*/
public static void setStatusBarColor(Activity activity , int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
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);
// 狀態(tài)欄(以上幾行代碼必須,參考setStatusBarColor|setNavigationBarColor方法源碼)
window.setStatusBarColor(Color.TRANSPARENT);
// 虛擬導(dǎo)航鍵
window.setNavigationBarColor(color);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//使用SystemBarTint庫(kù)使4.4版本狀態(tài)欄變色,需要先將狀態(tài)欄設(shè)置為透明
transparencyBar(activity);
SystemBarTintManager tintManager = new SystemBarTintManager(activity);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintResource(Color.TRANSPARENT);
}
}
/**
* 修改狀態(tài)欄文字顏色,這里小米,魅族區(qū)別對(duì)待。
*/
public static void setLightStatusBar(final Activity activity, final boolean dark) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
switch (RomUtils.getLightStatusBarAvailableRomType()) {
case RomUtils.AvailableRomType.MIUI:
MIUISetStatusBarLightMode(activity, dark);
break;
case RomUtils.AvailableRomType.FLYME:
setFlymeLightStatusBar(activity, dark);
break;
case RomUtils.AvailableRomType.ANDROID_NATIVE:
setAndroidNativeLightStatusBar(activity, dark);
break;
}
}
}
public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
boolean result = false;
Window window = activity.getWindow();
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//狀態(tài)欄透明且黑色字體
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字體
}
result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && RomUtils.isMiUIV7OrAbove()) {
//開(kāi)發(fā)版 7.7.13 及以后版本采用了系統(tǒng)API,舊方法無(wú)效但不會(huì)報(bào)錯(cuò),所以兩個(gè)方式都要加上
if (dark) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
} catch (Exception e) {
}
}
return result;
}
private static boolean setFlymeLightStatusBar(Activity activity, boolean dark) {
boolean result = false;
if (activity != null) {
try {
WindowManager.LayoutParams lp = activity.getWindow().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);
activity.getWindow().setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
return result;
}
private static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
View decor = activity.getWindow().getDecorView();
if (dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
//隱藏虛擬按鍵:
public static void hideBottomUIMenu(Activity activity) {
//隱藏虛擬按鍵,并且全屏
/* activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);*/
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = activity.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView =activity.getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
//這個(gè)也可以:
public static void hideNavigationBar(Activity activity) {
int uiFlags = 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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN; // hide status bar
if (android.os.Build.VERSION.SDK_INT >= 19) {
uiFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE;//0x00001000; // SYSTEM_UI_FLAG_IMMERSIVE_STICKY: hide
} else {
uiFlags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
try {
activity.getWindow().getDecorView().setSystemUiVisibility(uiFlags);
} catch (Exception e) {
// TODO: handle exception
}
}
}
package com.paff.myapplication.utils;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class RomUtils {
class AvailableRomType {
public static final int MIUI = 1;
public static final int FLYME = 2;
public static final int ANDROID_NATIVE = 3;
public static final int NA = 4;
}
public static int getLightStatusBarAvailableRomType() {
//開(kāi)發(fā)版 7.7.13 及以后版本采用了系統(tǒng)API,舊方法無(wú)效但不會(huì)報(bào)錯(cuò)
if (isMiUIV7OrAbove()) {
return AvailableRomType.ANDROID_NATIVE;
}
if (isMiUIV6OrAbove()) {
return AvailableRomType.MIUI;
}
if (isFlymeV4OrAbove()) {
return AvailableRomType.FLYME;
}
if (isAndroidMOrAbove()) {
return AvailableRomType.ANDROID_NATIVE;
}
return AvailableRomType.NA;
}
//Flyme V4的displayId格式為 [Flyme OS 4.x.x.xA]
//Flyme V5的displayId格式為 [Flyme 5.x.x.x beta]
private static boolean isFlymeV4OrAbove() {
String displayId = Build.DISPLAY;
if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) {
String[] displayIdArray = displayId.split(" ");
for (String temp : displayIdArray) {
//版本號(hào)4以上,形如4.x.
if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) {
return true;
}
}
}
return false;
}
//Android Api 23以上
private static boolean isAndroidMOrAbove() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static boolean isMiUIV6OrAbove() {
try {
final Properties properties = new Properties();
properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
if (uiCode != null) {
int code = Integer.parseInt(uiCode);
return code >= 4;
} else {
return false;
}
} catch (final Exception e) {
return false;
}
}
static boolean isMiUIV7OrAbove() {
try {
final Properties properties = new Properties();
properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
if (uiCode != null) {
int code = Integer.parseInt(uiCode);
return code >= 5;
} else {
return false;
}
} catch (final Exception e) {
return false;
}
}
}