Android实现修改状态栏背景、字体和图标颜色的方法

前言:

Android开发,对于状态栏的修改,实在是不友好,没什么api可以用,不像ios那么方便.但是ui又喜欢只搞ios一套.没办法.各种翻源码,写反射.真的蛋疼.

需求场景:

当toolbar及状态栏需要为白色或浅色时(如简书),状态栏由于用的Light风格Theme,字体,图标也都是白色,会看不清.如果改变成黑色就很和谐了.

一.修改状态栏颜色:

改变状态栏颜色,可以看看这篇文章.传送门:实现状态栏(statusbar)渐变效果其实很简单

传送门实现的效果:

这种方法实现的状态栏变色,没有黑色背景.

使用全屏模式实现的效果如下(QQ的效果):

很明显的黑色背景.

我用的手机是华为,系统7.0

二.修改状态栏字体:

通用工具类:

public class StatusBarUtil {

  /**
   * 设置状态栏黑色字体图标,
   * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
   *
   * @return 1:MIUUI 2:Flyme 3:android6.0
   */
  public static int getStatusBarLightMode(Window window) {
    int result = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      if (MIUISetStatusBarLightMode(window, true)) {
        result = 1;
      } else if (FlymeSetStatusBarLightMode(window, true)) {
        result = 2;
      } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        result = 3;
      } else {//5.0

      }
    }
    return result;
  }

  /**
   * 已知系统类型时,设置状态栏黑色字体图标。
   * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
   */
  public static void setStatusBarLightMode(Window window) {
    int type = getStatusBarLightMode(window);
    if (type == 1) {
      MIUISetStatusBarLightMode(window, true);
    } else if (type == 2) {
      FlymeSetStatusBarLightMode(window, true);
    } else if (type == 3) {
      window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    } else {//5.0

    }
  }

  /**
   * 清除MIUI或flyme或6.0以上版本状态栏黑色字体
   */
  public static void StatusBarDarkMode(Window window) {
    int type = getStatusBarLightMode(window);
    if (type == 1) {
      MIUISetStatusBarLightMode(window, false);
    } else if (type == 2) {
      FlymeSetStatusBarLightMode(window, false);
    } else if (type == 3) {
      window.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 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);//状态栏透明且黑色字体
        } else {
          extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
        }
        result = true;
      } catch (Exception e) {

      }
    }
    return result;
  }

}

activity中使用:

StatusBarUtil.setStatusBarLightMode(getWindow());

效果:

出现的问题:

1.statusbar背景色变成了colorPrimaryDark默认颜色,但是我的配置是白色背景(具体配置代码见最后).

分析原因:

setSystemUiVisibility()会刷新view的属性配置.由于statusbar默认使用colorPrimaryDark属性.所以颜色会变回默认颜色

此时步骤一设置背景的方法就会失效.

  private void initStatusBar() {
    if (statusBarView == null) {
      int identifier = getResources().getIdentifier("statusBarBackground", "id", "android");
      statusBarView = getWindow().findViewById(identifier);
    }
    if (statusBarView != null) {
      statusBarView.setBackgroundResource(MVPConfig.statusDrawable);
    }
  }

原因:当传入的resid相同时,就不会再次去设置背景色.

解决办法:

  private void initStatusBar() {
    if (statusBarView == null) {
      int identifier = getResources().getIdentifier("statusBarBackground", "id", "android");
      statusBarView = getWindow().findViewById(identifier);
    }
    if (statusBarView != null) {
      statusBarView.setBackgroundDrawable(null);//在设置前将背景设置为null;
      statusBarView.setBackgroundResource(MVPConfig.statusDrawable);
    }
  }

修改后的效果:

三.完整代码:

1.MvpConfig

public class MVPConfig {
  public static int statusDrawable;
  public static int toolbarBackgroundColor;
  public static int toolbarBackgroundDrawable;
  public static int backDrawable;
  public static boolean isStatusBarLight;

  public static void setStatusbarDrawable(@DrawableRes int statusDraw) {
    statusDrawable = statusDraw;
  }

  public static boolean isStatusBar() {
    return statusDrawable > 0;
  }

  public static void setToolbarDrawable(int toolbarBackgroundDrawable) {
    MVPConfig.toolbarBackgroundDrawable = toolbarBackgroundDrawable;
  }

  public static void setBackDrawable(int backDrawable) {
    MVPConfig.backDrawable = backDrawable;
  }

  public static void setIsStatusBarLight(boolean isStatusBarLight) {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
      MVPConfig.statusDrawable = Color.parseColor("#33ffffff");
    }
    MVPConfig.isStatusBarLight = isStatusBarLight;
  }

2.Application中

@Override
  public void onCreate() {
    super.onCreate();
    MVPConfig.setToolbarDrawable(R.color.white);
    MVPConfig.setStatusbarDrawable(R.color.white);
    MVPConfig.setBackDrawable(R.drawable.back);
    MVPConfig.setIsStatusBarLight(true);
}

3.BaseActivity

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 //延时加载数据.
    Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
      @Override
      public boolean queueIdle() {
        if (isStatusBarLight()) {
          StatusBarUtil.setStatusBarLightMode(getWindow());
        }
        if (isStatusBar()) {
          initStatusBar();
          getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
              initStatusBar();
            }
          });
        }
        mPresenter.initData();
        return false;
      }
    });
  }

 private void initStatusBar() {
    if (statusBarView == null) {
      int identifier = getResources().getIdentifier("statusBarBackground", "id", "android");
      statusBarView = getWindow().findViewById(identifier);
    }
    if (statusBarView != null) {
      if (isStatusBarLight()) {
        statusBarView.setBackgroundDrawable(null);
      }
      statusBarView.setBackgroundResource(MVPConfig.statusDrawable);
    }
  }
  //子类通过复写该方法,控制是否改变statusbar
  protected boolean isStatusBar() {
    return MVPConfig.isStatusBar();
  }
//子类通过复写该方法,控制是否需要改变statusbar字体颜色
  protected boolean isStatusBarLight() {
    return MVPConfig.isStatusBarLight;
  }

四.补充:

6.0以下,5.0原生系统无法修改字体颜色,用了个比较取巧的办法,设置成半透明灰色.

 public static void setStatusBarLightMode(Window window) {
    int type = getStatusBarLightMode(window);
    if (type == 1) {
      MIUISetStatusBarLightMode(window, true);
    } else if (type == 2) {
      FlymeSetStatusBarLightMode(window, true);
    } else if (type == 3) {
      window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    } else {
      //5.0
      if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
        MVPConfig.statusDrawable = Color.parseColor("#33ffffff");
      }
    }
  }

由于是直接修改window中的statusbarview的背景,而frgament依赖于activity,所以在activity与fragment直接跳转时,状态栏不是很适用.比如:activity是蓝色,fragment需要是白色,fragment需要通过window修改状态栏颜色.有点麻烦.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android如何自定义EditText光标与下划线颜色详解

    前言 最近在写些小Demo复习基础,在用到EditText的时候突然发现之前几乎没有注意到它的光标和下划线的颜色,于是花了不少时间,看了不少博客,现在就来总结和分享一下收获,话不多说了,来一起看看详细的介绍: 1.第一印象:原生的EditText 我们要在原生的EditText上修改,首先当然要认识一下它的本来面目.在Android Studio中新建一个工程,让MainActivity继承于AppCompatActivity(为什么要这样做,后面再说),然后在MainActivity的布局中放

  • Android 改变图标原有颜色和搜索框的实例代码

    图标改变颜色:Drawable的变色,让Android也能有iOS那么方便的图片色调转换,就像同一个图标,但是有多个地方使用,并且颜色不一样,就可以用这个方法了. 搜索框: 一般是EditText实现,本文 实现 TextView图片和文字居中,键盘搜索. 来看看效果图: 图标改变颜色:第一个界面的左边(二维码)和右边(更多)两个实现,我放进去的图片是黑色的,显示出来是白色的. 搜索框:第一个界面的图片和文字居中,还可以设置间距,第二个见面搜索设置键盘搜索按钮,点击搜索监听事件,清除内容的图标.

  • Android编程之ProgressBar圆形进度条颜色设置方法

    本文实例讲述了Android ProgressBar圆形进度条颜色设置方法.分享给大家供大家参考,具体如下: 你是不是还在为设置进度条的颜色而烦恼呢--别着急,且看如下如何解决. ProgressBar分圆形进度条和水平进度条 我这里就分享下如何设置圆形进度条的颜色吧,希望对大家会有帮助. 源码如下: 布局文件代码: <ProgressBar android:id="@+id/progressbar" android:layout_width="wrap_content

  • 修改Android FloatingActionButton的title的文字颜色及背景颜色实例详解

    修改Android FloatingActionButton的title的文字颜色及背景颜色实例详解 首先看一张图片 我是在一个不错的开源的FloatingActionButton库基础上实现的,链接github开源库 参考图片的标记和代码里的注释.代码如下: <com.getbase.floatingactionbutton.FloatingActionsMenu android:id="@+id/fab_meau" android:layout_width="wra

  • Android中的颜色表示的详解

    Android中的颜色表示 在Android中颜色用一个32位整数来表示,32位整数包含4个字节,其中第一个字节代表该颜色的透明度(Alpha),0表示完全透明,0xFF表示完全不透明.第2,3,4字节分别代表该颜色在RGB颜色空间中红色(R),绿色(G)和蓝色(B)三个颜色分量的值,0代表没有该颜色分量,0xFF代表该颜色分量达到最大.例如0xCCFF0000表示80%透明度的红色. XML中的颜色表示 在XML中用#加颜色值来表示一个颜色,例如#FFA1A100.如果透明度为0xFF,即完全

  • Android修改DatePicker字体颜色及分割线颜色详细介绍

    一.DatePicker和TimePicker简介 DatePicker是一个日期选择控件,它继承自FrameLayout类,用来实现的主要功能是使用护可以方便选择日期.如果要捕获用户修改DataPicker控件中的数据改变事件,需要为DatePicker添加OnDateChangedListener监听器. TimePicker是一个时间选择控件,也继承自FrameLayout类.时间选择控件向用户显示一天中的时间(可以为24小时,也可以为AM/PM制),并允许用户进行选择.如果要捕获用户修改

  • Android 设置颜色的方法总结

    Android 设置颜色的方法总结 Android中有几种设置界面背景及文字颜色的方法,下面由浅入深分别介绍Android中设置颜色的几种方法: 1.直接在布局文件中设置: android:backgound="#FFFFFFFF", android:textcolor="#00000000" 2.把颜色提取出来形成资源,放在资源文件下面(values/drawable/color.xml): <?xml version="1.0" enc

  • Android编程实现自定义渐变颜色效果详解

    本文实例讲述了Android编程实现自定义渐变颜色效果.分享给大家供大家参考,具体如下: 你是否已经厌恶了纯色的背景呢?那好,Android提供给程序员自定义渐变颜色的接口,让我们的界面炫起来吧. xml定义渐变颜色 首先,你在drawable目录下写一个xml,代码如下 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.

  • Android实现修改状态栏背景、字体和图标颜色的方法

    前言: Android开发,对于状态栏的修改,实在是不友好,没什么api可以用,不像ios那么方便.但是ui又喜欢只搞ios一套.没办法.各种翻源码,写反射.真的蛋疼. 需求场景: 当toolbar及状态栏需要为白色或浅色时(如简书),状态栏由于用的Light风格Theme,字体,图标也都是白色,会看不清.如果改变成黑色就很和谐了. 一.修改状态栏颜色: 改变状态栏颜色,可以看看这篇文章.传送门:实现状态栏(statusbar)渐变效果其实很简单 传送门实现的效果: 这种方法实现的状态栏变色,没

  • android开发修改状态栏背景色和图标颜色的示例

    本文介绍了android开发修改状态栏背景色和图标颜色的示例,分享给大家,具体如下: 修改状态栏背景色和图标颜色 默认是黑底白字的,现在要改为白底黑字的 先看下效果图: 1.状态栏背景是白色: 在style中设置 <item name="colorPrimaryDark">@color/white</item> 2.写修改状态栏图标的颜色(暂时只知道黑色和白色) public class StatusBarUtil { /** * 修改状态栏为全透明 * @pa

  • android 更改TextView中任意位置字体大小和颜色的方法

    这里介绍两种方法,一种是Spannable,一种是Html.fromHtml(通过html标签来改变),实际中看您使用哪种方便选择使用即可 1.Html.fromHtml的使用 TextView textView = (TextView) findViewById(R.id.text); String textSource = "修改TextView中部分文字的<font color='#ff0000'><big>大</big><small>小&l

  • jquery实现实时改变网页字体大小、字体背景色和颜色的方法

    本文实例讲述了jquery实现实时改变网页字体大小.字体背景色和颜色的方法.分享给大家供大家参考.具体如下: 这里使用jquery实时改变字体大小.字体背景色和颜色,JQUERY让很多事变得更简单,确实是个实用的小插件,对JQ不熟悉的朋友,平时可要多看一些实例啦,比如现在这一个小实例,你可以从中学习到不少知识点的哦. 运行效果如下图所示: 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

  • Android中修改TabLayout底部导航条Indicator长短的方法

    前言 对于Tablayout相信大家都不陌生,在开发中使用的应该很频繁了,但是底部导航条长短是固定死的,需要自己来改动长短,找了半天没找着方法,看了下官方建议,可以通过映射来修改自己想要的长短,其实也就几行代码的问题. 看代码: public static void setIndicator(Context context, TabLayout tabs, int leftDip, int rightDip) { Class<?> tabLayout = tabs.getClass(); Fi

  • iOS设置UIButton文字显示位置和字体大小、颜色的方法

    前言 大家都知道UIButton按钮是IOS开发中最常用的控件,作为IOS基础学习教程知识 ,初学者需要了解其基本定义和常用设置,以便在开发在熟练运用. 一.iOS设置UIButton的字体大小 btn.frame = CGRectMake(x, y, width, height); [btn setTitle: @"search" forState: UIControlStateNormal]; //设置按钮上的自体的大小 //[btn setFont: [UIFont system

  • Android开发实现按钮点击切换背景并修改文字颜色的方法

    本文实例讲述了Android开发实现按钮点击切换背景并修改文字颜色的方法.分享给大家供大家参考,具体如下: 其实原理很简单,用到的是selector,用来设置android:background和android:textcolor属性,selector可以用来设置默认时候.点击时候的背景图片和文字颜色的属性,过程如下: 这两个文件如下: 1.当点击按钮,改变文字的颜色: <?xml version="1.0" encoding="utf-8"?> <

  • Android系统更改状态栏字体颜色

    随着时代的发展,Android的状态栏都不是乌黑一片了,在Android4.4之后我们可以修改状态栏的颜色或者让我们自己的View延伸到状态栏下面.我们可以进行更多的定制化了,然而有的时候我们使用的是淡色的颜色比如白色,由于状态栏上面的文字为白色,这样的话状态栏上面的文字就无法看清了.因此本文提供一些解决方案,可以是MIUI6+,Flyme4+,Android6.0+支持切换状态栏的文字颜色为暗色. 修改MIUI public static boolean setMiuiStatusBarDar

  • Android实现的状态栏定制和修改方法

    本文实例讲述了Android实现的状态栏定制和修改方法.分享给大家供大家参考.具体如下: 大家都知道定制在android开发中的重要性,因为通过定制,你才能制造出差异化的产品,才能满足更多消费者的需求, 像HTC生产的手机都通过了深层次的二次开发,今天我也来分享一下我的状态栏定制. 废话不说了,直接上图: 主要更换了背景,文字颜色以及icon的显示顺序. 2. 关键代码部分 a) 代码在系统中的位置 status bar 的相关代码位于:frameworks/base/services/java

  • Android中正确使用字体图标(iconfont)的方法

    字体图标 字体图标是指将图标做成字体文件(.ttf),从而代替传统的png等图标资源. 使用字体图标的优点和缺点分别为: 优点: 1. 可以高度自定义图标的样式(包括大小和颜色),对于个人开发者尤其适用 2. 可以减少项目和安装包的大小(特别你的项目中有很多图片icon时,效果将是M级) 3. 几乎可以忽略屏幕大小和分辨率,做到更好的适配 4. 使用简单 -- 缺点:        1. 只能是一些简单的icon,不能代替如背景图.9图等资源 2. 一些需要文字说明的icon,图片资源将会是更好

随机推荐