android状态栏背景色和图标颜色更改总结

通过若干种方法来实现状态栏背景和图标变色

注意事项:api 23才支持状态栏图标变色,所以图标变色会在编译api>=23中实现
一 Android 4.4 之前状态栏默认黑色,不能改变
二 Android 4.4 可以设置状态栏是否透明
三 Android 5.0+ 可以主动设置状态栏背景

1 直接代码改变状态栏颜色和图标颜色
对于api在23以上的手机一行代码可以解决 StatusBarUtils.setStatusBar(getResources().getColor(R.color.text_white),MainActivity.this);

2 使用android:fitsSystemWindows
查看6.2
3 使用paddingtop
在api>=19情况下,设置状态栏透明,然后在根布局中设置paddingtop=25dp,可以让状态栏背景色和标题栏颜色一致。用android:fitsSystemWindows效果一样,这种方式使用起来
需要在每个根布局中使用,用起来麻烦。不推荐使用。

4 整理小米和魅族手机状态栏兼容方案

/**
 *状态栏亮色模式,设置状态栏黑色文字、图标,
 * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
 * @param activity
 * @return 1:MIUUI 2:Flyme 3:android6.0
 */
public static int StatusBarLightMode(Activity activity){
    int result=0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        if(MIUISetStatusBarLightMode(activity, true)){
            result=1;
        }else if(FlymeSetStatusBarLightMode(activity.getWindow(), true)){
            result=2;
        }else 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);
            result=3;
        }
    }
    return result;
}

/**
 * 已知系统类型时,设置状态栏黑色文字、图标。
 * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
 * @param activity
 * @param type 1:MIUUI 2:Flyme 3:android6.0
 */
public static void StatusBarLightMode(Activity activity,int type){
    if(type==1){
       MIUISetStatusBarLightMode(activity, true);
    }else if(type==2){
        FlymeSetStatusBarLightMode(activity.getWindow(), true);
    }else if(type==3){
        activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    }

}

/**
 * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
 */
public static void StatusBarDarkMode(Activity activity,int type){
    if(type==1){
        MIUISetStatusBarLightMode(activity, false);
    }else if(type==2){
        FlymeSetStatusBarLightMode(activity.getWindow(), false);
    }else if(type==3){
        activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
    }

}


/**
 * 设置状态栏图标为深色和魅族特定的文字风格
 * 可以用来判断是否为Flyme用户
 * @param window 需要设置的窗口
 * @param dark 是否把状态栏文字及图标颜色设置为深色
 * @return  boolean 成功执行返回true
 *
 */
public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
    boolean result = false;
    if (window != null) {
        try {
            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);
            result = true;
        } catch (Exception e) {

        }
    }
    return result;
}

 /**
 * 需要MIUIV6以上
 * @param activity
 * @param dark 是否把状态栏文字及图标颜色设置为深色
 * @return  boolean 成功执行返回true
 *
 */
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);//状态栏透明且黑色字体
            }else{
                extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
            }
            result=true;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
                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_VISIBLE);
                }
            }
        }catch (Exception e){

        }
    }
    return result;
}

5 对于api大于等于21小于23情况分析

仅仅只需要在color文件夹中改变 colorPrimaryDark的颜色(或者参照1中的方案,也可以实现效果),但图标字体颜色无法改变
Yes it’s possible to change it to gray (no custom colors) but this only works from API 23 and above you only need to add this in your values-v23/styles.xml
true

6 对于api大于等于19小于21情况分析
注意事项:
6.1 主题是Fullscreen,状态栏会不发生变化,因为Fullscreen属性会默认状态栏不可见

<style name="AppTheme" parent="android:Theme.Light.NoTitleBar">
<!--<style name="AppTheme" parent="android:Theme.DeviceDefault.Light.DarkActionBar">-->

6.2 如果主题中使用了标题栏 actionbar之类的,标题栏会被顶上去,解决办法 android:fitsSystemWindows=“true”
或者这样设置
ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
View mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
//注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . 预留出系统 View 的空间.
mChildView.setFitsSystemWindows(fitSystemWindows);
}

7适配全面屏:

7.1
因此建议开发者声明 Maximum Aspect Ratio > 2 或更多。值得一提的是,如果应用的 android:resizeableActivity 已经设置为 true,就不必设置 Maximum Aspect Ratio 了。详见官方文档 Declaring maximum aspect ratio。
http://www.easemob.com/news/973

7.2 全面屏介绍
https://developer.huawei.com/consumer/cn/devservice/doc/50111
7.2.1全面屏定义
普通屏:纵横比为16:9,如1080x1920、1440x2560等,其比值为1.78,全面屏手机出现之前,Android中默认的最大屏幕纵横比(maximum aspect ratio)为1.86,即能够兼容16:9的屏幕。

全面屏:屏幕比例超过1.86的屏幕,比如:17:9、18:9、19:9、19.5:9 等这些比例的屏幕都是全面屏。

7.2.2 全面屏机型
机型 屏幕纵横比 ratio_float
Mate10 pro 18:9 2.0
LG G6 18:9 2.0
Samsung Galaxy S8 18.5:9 2.06
Essential Phone 19:10 1.9
小米MIX
17:9 1.89
iPhone X 19.5:9 2.17

8
华为手机底部虚拟导航栏遮挡布局解决方案
8.1 发现有虚拟导航的时候,改变布局高度
activity.getWindow().getDecorView().findViewById(android.R.id.content).setPadding(0, 0, 0, getNavigationBarHeight(activity));

public static int getNavigationBarHeight(Context context) {
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
if (!hasMenuKey && !hasBackKey) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier(“navigation_bar_height”, “dimen”, “android”);//获取NavigationBar的高度
int height = resources.getDimensionPixelSize(resourceId);
return height;
} else {
return 0;
}
}

8.2
让底部状态栏透明,不过这种会让导航栏图标颜色变白(不美观)
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

发布了277 篇原创文章 · 获赞 84 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/qq_26296197/article/details/88533294
今日推荐