添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 之所以提到透明状态栏,是我们通常所需要的给状态栏设置颜色的原理就是这里的透明概念。(Android4.4)API 19 没有提供单独设置“状态栏”颜色的方法 ,如果要设置,就需要把View的最上端设置出一定高度的颜色(或者图案),具体高度只要大于等于“状态栏”高度即可,那么已经“透明”了的“状态栏”自然而然就会变成这个颜色(或者图案)。从而达到设置状态栏有颜色的样子。所以可以说是有色状态栏为透明状态栏的一种。因为是以透明状态栏为基础。
  • 但这限于Android5.0以下设置颜色的原理,在5.0之后就提供API可以直接设置颜色了。
  • 四、给状态栏设置颜色

    经常会看到这些词:着色状态栏、变色状态栏、单色状态栏
    放几张图片,以下就是我们常用状态栏的样式。

    大家通常又通常把状态栏和导航栏颜色不一样称作变色状态栏,一样称作单色状态栏、😁、这些名称大家都是自己随意命名的,只要知道是怎么回事就好、说白了就是给 状态栏设置颜色
    【给状态栏设置颜色】我们要分为两种情况
    1.Android4.4以上&&Android5.0以下(API大于等于19小于21)

    记得我们上面讲过(Android4.4)API 19没有提供单独设置“状态栏”颜色的方法,如果要设置,就需要把View的最上端设置出一定高度的颜色(或者图案),具体高度只要大于等于“状态栏”高度即可,那么已经“透明”了的“状态栏”自然而然就会变成这个颜色(或者图案)。从而达到设置状态栏有颜色的样子。原理就是4.4提出的透明概念

    2.Android5.0以上(API大于等于21)

    在5.0我们都知道提出了MaterialDesign的UI设计,导航栏也变成了Toolbar、google默认都会把我们的两栏设置为一深一浅的颜色,你可以说这是变色状态栏,但不是 沉浸 !!我们可以直接通过系统的colorPrimaryDark等颜色值直接修改状态栏的颜色。

  • 或者隐藏状态栏。而隐藏状态栏也分为两种。
  • 沉浸式全屏(我们在前面提到的):比如我们看小说、玩游戏时,在沉浸式全屏状态下,对屏幕的操作并不会唤出系统栏。想要唤出系统栏,你必须从屏幕的上/下边缘向屏幕内划入。
  • 普通全屏:还有一种是类似看视频,通常我们的手指不会碰触屏幕,此时点击屏幕,状态栏就会出现。

    重点 :只有4.4以后才可以设置,4.4以下只会显示默认状态栏。
    4.4以后之所以可以设置,是因为API新添属性windowTranslucentStatus.

    关于设置透明栏我们有两种方式,第一种是通过xml设置,第二种是使用代码设置。推荐代码方式。
    通过xml:新建values-v19文件夹,同时新建styles.xml,为activity的Style 添加一个属性,然后在配置文件给相应的activity设置android:theme
    <style name="AppTheme" parent="BaseTheme">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    
    通过代码设置:
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
          Window window = activity.getWindow();
          window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    

    我们看一下效果

    二、有色状态栏

    正常标题栏是黑底白字,但有的时候我们的主题背景是浅色,那肯定希望字体颜色为黑色比较好,这时我们需要根据浅色主题做适配,目前可以应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android 。

       //有色状态栏,想要和导航栏颜色不一样就设置不一样的颜色即可
        public static void setWindowStatusBarColor(Activity activity, int color, boolean isLightMode) {
            Log.d("StatusBar", "Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
            int statusColor = color;
            //如果是浅色主题  可将状态栏图标和文字内容改为黑色样式 实现浅色主题调背景的状态栏效果
            //只应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (isLightMode) {
                    int mode = StatusBarLightMode(activity);
                    //0代表浅色主题没有设置成功
                    if (mode == 0) {
                        statusColor = activity.getResources().getColor(R.color.status_bar_dark);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                activity.getWindow().setStatusBarColor(statusColor);
                return;
            //4.4以上,5.0以下
            //原理:只要在根布局去设置一个与状态栏等高的View,设置背景色为我们期望的颜色就可以
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
                View statusBarView = new View(activity);
                ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                statusBarView.setBackgroundColor(statusColor);
                contentView.addView(statusBarView, lp);
    

    三、全屏模式

    1.全屏模式之带状态栏(内容可伸展到状态栏,比如抖音)

    页面顶部的图片内容延伸至状态栏中,这种做法其实就是单独使用 <item name="android:windowTranslucentStatus">true</item> 样式,不在 layout 布局文件中添加 android:fitsSystemWindows="true" 属性。

    通过设置style方式:

          <item name="android:windowTranslucentStatus">true</item>
    //如果要取消标题栏
          <item name="windowActionBar">false</item>
           <item name="windowNoTitle">true</item>
    
        //带状态栏的全屏--内容可伸展到状态栏
        public static void setFullScreenWithStatusBar(Activity activity){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // 设置状态栏透明
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                //  设置根布局的参数
                //将根rootView直接顶上去,和状态栏的顶部对齐。
                ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
                ViewCompat.setFitsSystemWindows(rootView,false);
                rootView.setClipToPadding(true);
    

    2.全屏模式之无状态栏

    之一:沉浸式状态栏实现

    ⚠️:切结给状态栏改个颜色不代表就是沉浸!
    我们想要的沉浸效果:开启沉浸模式后,状态栏消失,也就是全屏拓展,当从顶部向下滑动,状态栏出现,退出沉浸模式,状态栏也出现了。

    因为这个也不是通用的,就没有封装进去,如果有这个需求,参考这篇文章自行设置Android 实现沉浸式状态栏

    之二:普通全屏

    1.设置style

  • 只是全屏:指定theme为android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  • 全屏并透明:指定theme为android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
  • 2.或代码实现

      //普通全屏
        public static void setFullScreenNoStatusBar(Activity activity){
            activity.getWindow().
                    setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    

    最后放上全部代码

    public class StatusBarUtils {
        // 使Activity布局填充状态栏
        public static void fillStatusBar(Activity activity) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                View decorView = activity.getWindow().getDecorView();
                int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                decorView.setSystemUiVisibility(option);
                activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //透明状态栏
        public static void setTranslucentStatusbar(Activity activity) {
            Window window = activity.getWindow();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                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);
                window.setStatusBarColor(Color.TRANSPARENT);
                window.setNavigationBarColor(Color.TRANSPARENT);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // 透明状态栏
                //必须要有windowTranslucentStatus这个属性
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                // 透明导航栏
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
                ViewCompat.setFitsSystemWindows(rootView, true);
         * @param activity
         * @param color
         * @param isLightMode
        //有色状态栏,想要和导航栏颜色不一样就设置不一样的颜色即可
        public static void setWindowStatusBarColor(Activity activity, int color, boolean isLightMode) {
            Log.d("StatusBar", "Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
            int statusColor = color;
            //如果是浅色主题  可将状态栏图标和文字内容改为黑色样式 实现浅色主题调背景的状态栏效果
            //只应用于4.4以上版本MIUIV、Flyme和6.0(API 23)以上版本其他Android
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (isLightMode) {
                    int mode = StatusBarLightMode(activity);
                    //0代表浅色主题没有设置成功
                    if (mode == 0) {
                        statusColor = activity.getResources().getColor(R.color.status_bar_dark);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //使用setStatusBarColor的前提条件 取消FLAG_TRANSLUCENT_STATUS
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                activity.getWindow().setStatusBarColor(statusColor);
                return;
            //4.4以上,5.0以下
            //原理:只要在根布局去设置一个与状态栏等高的View,设置背景色为我们期望的颜色就可以
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
                View statusBarView = new View(activity);
                ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        getStatusBarHeight(activity));
                statusBarView.setBackgroundColor(statusColor);
                contentView.addView(statusBarView, lp);
        //得到系统statusbar的高度
        public static int getStatusBarHeight(Context context) {
            int result = 0;
            int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = context.getResources().getDimensionPixelSize(resourceId);
            return result;
        //全屏布局实现方式1
        //带状态栏的全屏--内容可伸展到状态栏
        public static void setFullScreenWithStatusBar(Activity activity) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // 设置状态栏透明
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                //  设置根布局的参数
                //将根rootView直接顶上去,和状态栏的顶部对齐。
                ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
                ViewCompat.setFitsSystemWindows(rootView, false);
                rootView.setClipToPadding(true);
        //不带状态栏的全屏
        public static void setFullScreenNoStatusBar(Activity activity) {
            activity.getWindow().
                    setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //全屏布局实现方式2
        public static void setFullScreen(Activity activity, boolean isHavaStatusBar) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (isHavaStatusBar) {
                    //带状态栏的全屏
                    activity.getWindow().getDecorView().setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_FULLSCREEN
                                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
                } else {
                    //不带状态栏的全屏
                    activity.getWindow().getDecorView().setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
         * 设置状态栏黑色字体图标,
         * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
         * @param activity
         * @return 1:MIUUI 2:Flyme 3:android6.0 0:为没有设置浅色主题成功
        public static int StatusBarLightMode(Activity activity) {
            int result = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (DeviceUtils.isMiui() && MIUISetStatusBarLightMode(activity.getWindow(), true)) {
                    result = 1;
                    //miui android 7.0无法通过反射修改
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                        result = 3;
                        Log.d("statusbar1", "api method");
                } 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;
         * 设置状态栏图标为深色和魅族特定的文字风格
         * 可以用来判断是否为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 window 需要设置的窗口
         * @param dark   是否把状态栏字体及图标颜色设置为深色
         * @return boolean 成功执行返回true
        public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
            boolean result = false;
            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);//状态栏透明且黑色字体
                        Log.d("statusbar1", "miui method: 1");
                    } else {
                        extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
                        Log.d("statusbar1", "miui method: 2");
                    result = true;
                } catch (Exception e) {
                    Log.d("statusbar1", "miui method: error");
            return result;