android沉浸式 字体,全面解析android沉浸式状态栏
一、沉浸式實(shí)現(xiàn)方式
實(shí)現(xiàn)沉浸式狀態(tài)樣主要有兩種方式,一種是通過(guò)設(shè)置theme來(lái)實(shí)現(xiàn),另一種是代碼中實(shí)現(xiàn)
1.1通過(guò)設(shè)置theme來(lái)實(shí)現(xiàn)
通過(guò)theme設(shè)置也有兩種方法
方法一:
values/style.xml
values-v19/style.xml
true
true
values-v21/style.xml
false
true
@android:color/transparent
方法二:
直接在values/style.xml中通過(guò)函數(shù)API進(jìn)行區(qū)分
true
true
@android:color/transparent
1.2 代碼中設(shè)置
/**
* 通過(guò)設(shè)置全屏,設(shè)置狀態(tài)欄透明
*
* @param activity
*/
private void fullScreen(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
View decorView = window.getDecorView();
//兩個(gè) flag 要結(jié)合使用,表示讓?xiě)?yīng)用的主體內(nèi)容占用系統(tǒng)狀態(tài)欄的空間
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//設(shè)置狀態(tài)欄為透明,否則在部分手機(jī)上會(huì)呈現(xiàn)系統(tǒng)默認(rèn)的淺灰色
window.setStatusBarColor(Color.TRANSPARENT);
//導(dǎo)航欄顏色也可以考慮設(shè)置為透明色
//window.setNavigationBarColor(Color.TRANSPARENT);
} else {
Window window = activity.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
attributes.flags |= flagTranslucentStatus;
// attributes.flags |= flagTranslucentNavigation;
window.setAttributes(attributes);
}
}
}
上面設(shè)置完之后,會(huì)出現(xiàn)頁(yè)面擠到狀態(tài)欄中去了,如下圖,
image.png
針對(duì)這種情況又有2種解決辦法,一種是設(shè)置android:fitsSystemWindows,另一種獲取狀態(tài)樣高度后,設(shè)置頁(yè)面的paddingTop值。
方案一:
values/style.xml中設(shè)置
true
true
@android:color/transparent
true
方案二:
首先通過(guò)反射獲取狀態(tài)欄高度
StatusBarCompat.class
public static int getStatusBarHeight(Context context) {
int result = 0;
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = context.getResources().getDimensionPixelOffset(resId);
}
return result;
}
再獲取頁(yè)面的根布局設(shè)置paddingTop
final int statusHeight = StatusBarCompat.getStatusBarHeight(this);
root.mToolBar.setPadding(0, statusHeight, 0, 0);
修改后的效果:
image.png
二、狀態(tài)欄顏色修改
通過(guò)上面的設(shè)置可以實(shí)現(xiàn)狀態(tài)欄的沉浸效果,狀態(tài)欄顏色和字體顏色似乎不太近人意
android 5.0之后提供了修改狀態(tài)欄顏色的方法
window.setStatusColor(@ColorInt int color)
該方法的生效條件是給window添加LAG_DRAWS_SYSTEM_BAR_BACKGROUNDS并取消FLAG_TRANSLUCENT_STATUS屬性,android 4.4 需要用到SystemBarTintManager 輔助類(lèi),在build.gradle中引用compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
修改的狀態(tài)欄顏色的代碼如下:
/**
* 修改狀態(tài)欄顏色,支持4.4以上版本
* @param activity
* @param colorId
*/
public static void setStatusBarColor(Activity activity, int colorId) {
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(activity.getResources().getColor(colorId));
} 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(colorId);
}
}
三、狀態(tài)欄文字顏色修改
android 6.0以上才添加修改狀態(tài)欄字體顏色,修改相對(duì)比較麻煩點(diǎn),分為google原生、小米、魅族三種情況。
google原生狀態(tài)欄文字顏色修改
這個(gè)方法比較簡(jiǎn)單,通過(guò)切換DecorView兩個(gè)不同的標(biāo)志位
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);
}
}
小米系統(tǒng)狀態(tài)欄文字顏色修改
直接來(lái)代碼
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ò),所以?xún)蓚€(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;
}
魅族系統(tǒng)狀態(tài)欄文字顏色修改
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;
}
修改成功之后的效果圖
image.png
四、使用建議
android 6.0之前,不能夠修改狀態(tài)欄文字顏色,默認(rèn)的文字顏色是白色,所以,在6.0以下要設(shè)置狀態(tài)欄顏色不能設(shè)置為白色,為了防止文字和背景顏色相同。
我的使用,6.0以上白色狀態(tài)欄,黑色背景;6.0以下黑色狀態(tài)欄,白色背景
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
StatusBarUtils.setLightStatusBar(this, true);//黑色文字
StatusBarUtils.setStatusBarColor(this, R.color.white);//白色背景
}else {
//6.0以下默認(rèn)白色文字
StatusBarUtils.setStatusBarColor(this, R.color.black);//黑色背景
}
五、附加代碼
StatusBarUtils類(lèi)
/**
* Describe : 狀態(tài)欄設(shè)置工具
*/
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 colorId
*/
public static void setStatusBarColor(Activity activity, int colorId) {
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(activity.getResources().getColor(colorId));
}
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(colorId);
}
}
/**
* 修改狀態(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ò),所以?xún)蓚€(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);
}
}
}
RomUtils類(lèi)代碼:
/**
* Describe : rom 工具
*/
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;
}
}
總結(jié)
以上是生活随笔為你收集整理的android沉浸式 字体,全面解析android沉浸式状态栏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2015美国数学建模a代码c语言,198
- 下一篇: 什么是Complement(补码)?