Android6.0以下改变沉浸式导航栏字体方法(仅对部分手机有效)
该方法只对部分Android6.0以下的手机有效,(颜色可以成功修改),无效的情况是导航栏半透明状态,可以看到字体。
Android沉浸式导航栏很普遍,可以让状态栏和手机自带的标题栏“融为一体”,看上去更为美观,但如果UI给的设计图,标题栏是白色,刚好你手机状态栏字体颜色也是白色,会导致看不见导航栏字体,如图:
对于这种情况,有小伙伴说了,MIUI和Flyme提供了开源代码设置状态栏的字体颜色,就像咱们搜索“Android改变标题栏字体颜色”后,出来的千篇一律的“StatusBarUtil”类一样,这个类确实对Android6.0的手机有用,
但是低版本手机呢?咱们先看一下这个类吧:
package com.matai.sharecar.utils;
import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 作者: www on 2019/8/27.
* 类说明:
*/
public class StatusBarUtil3 {
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
/**
* 设置状态栏文字色值为深色调
*
* @param useDart 是否使用深色调
* @param activity
*/
public static void setStatusTextColor(boolean useDart, Activity activity) {
if (isFlyme()) {//判断是否是魅族
processFlyMe(useDart, activity);//调用Flyme开源代码
} else if (isMIUI()) {//判断是否是小米
processMIUI(useDart, activity);//调用MIUI开源代码
} else {//两者均不是
if (useDart) {//如果设置了深色调
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}else{
//当不满足以上条件时,没有处理!!!!!
}
} else {//没有设置深色调
activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
}
/**
* 判断手机是否是魅族
*
* @return
*/
public static boolean isFlyme() {
try {
// Invoke Build.hasSmartBar()
final Method method = Build.class.getMethod("hasSmartBar");
return method != null;
} catch (final Exception e) {
return false;
}
}
/**
* 改变魅族的状态栏字体为黑色,要求FlyMe4以上
*/
private static void processFlyMe(boolean isLightStatusBar, Activity activity) {
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
try {
Class<?> instance = Class.forName("android.view.WindowManager$LayoutParams");
int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(lp);
Field field = instance.getDeclaredField("meizuFlags");
field.setAccessible(true);
int origin = field.getInt(lp);
if (isLightStatusBar) {
field.set(lp, origin | value);
} else {
field.set(lp, (~value) & origin);
}
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
/**
* 判断手机是否是小米
*
* @return
*/
public static boolean isMIUI() {
try {
final BuildProperties prop = BuildProperties.newInstance();
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (final IOException e) {
return false;
}
}
/**
* 改变小米的状态栏字体颜色为黑色, 要求MIUI6以上 lightStatusBar为真时表示黑色字体
*/
private static void processMIUI(boolean lightStatusBar, Activity activity) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
Class<? extends Window> clazz = activity.getWindow().getClass();
try {
int darkModeFlag;
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);
extraFlagField.invoke(activity.getWindow(), lightStatusBar? darkModeFlag : 0, darkModeFlag);
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
}
代码含义在注释中已经很详细了,使用方法是在MainActivity中:StatusBarUtil.setStatusTextColor(true,this);
效果如图:
但是在我的测试机上(vivo Android5.1)并没有修改成功……于是在网上找Funtouch OS系统怎么修改标题栏颜色,找到了这个方法:
/**
* 设置OPPO手机状态栏字体为黑色(colorOS3.0,6.0以下部分手机)
*
* @param lightStatusBar
* @param activity
*/
private static final int SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT = 0x00000010;
public static void setOPPOStatusTextColor(boolean lightStatusBar, Activity activity) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
int vis = window.getDecorView().getSystemUiVisibility();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (lightStatusBar) {
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (lightStatusBar) {
vis |= SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
} else {
vis &= ~SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
}
}
window.getDecorView().setSystemUiVisibility(vis);
}
测试后发现oppo手机上是有效的,在vivo上还是无效,后来发现这只适合部分os6.0以下的手机,但是不能让低版本的手机看不到标题栏啊,于是我想了一个简单粗暴的方法:
/**
* 设置状态栏文字色值为深色调
*
* @param useDart 是否使用深色调
* @param activity
*/
public static void setStatusTextColor(boolean useDart, Activity activity) {
if (isFlyme()) {//判断是否为魅族
processFlyMe(useDart, activity);//用Flyme开源代码
} else if (isMIUI()) {//判断是否为小米
processMIUI(useDart, activity);//用MIUI开源代码
} else if (Build.MANUFACTURER.equalsIgnoreCase("OPPO")) {//判断是否为oppo(可能有人说拟怎么不Build.MANUFACTURER.equalsIgnoreCase("vivo"))呢?你vivo不显示是不是因为这个呀?(答:并不是)
setOPPOStatusTextColor(useDart, activity);//
}else {//三者均不是
if (useDart) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}else{
//重点在这 直接设置死
activity.getWindow().getDecorView().setSystemUiVisibility(Color.parseColor("#000000"));
}
} else {
activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
}
之后我的手机上运行是这样的:标题栏虽然有了颜色 但是起码字能看见,我只能做到这了,有更好的办法的小伙伴 一定要告诉我啊啊啊啊啊!!!!
作为记录 希望能帮助到大家。