Android状态栏着色

版权声明:本文为博主原创文章,未经博主允许不得转载。

前言

  状态栏着色,也就是我们经常听到的沉浸式状态栏,关于沉浸式的称呼网上也有很多吐槽的,这里就不做过多讨论了,以下我们统称状态栏着色,这样我觉得更加容易理解。

  从Android4.4开始,才可以实现状态栏着色,并且从5.0开始系统更加完善了这一功能,可直接在主题中设置<item name="colorPrimaryDark">@color/colorPrimaryDark</item>或者getWindow().setStatusBarColor(color)来实现,但毕竟4.4+的机器还有很大的占比,所以就有必要寻求其它的解决方案。

  一般通过Android Studio新建项目时就实现了状态栏着色功能,不过只能在API>19的机型上正常显示。下面是通过Android studio新建项目时的默认样式代码:

styles.xml

colors.xml

AndroidManifest.xml

而本文想要实现的效果是在API>19和API<19的机型上都兼容状态栏着色效果。

效果图

API>19 API <=19

 

代码分析

  • 首先将手机手机状态栏透明化

  在values、values-v19、values-v21目录下分别创建相应的主题,然后在AndroidManifest.xml中给Application设置该主题。

   

  • 在布局文件中添加android:fitsSystemWindows="true"属性

  我们使用android:fitsSystemWindows="true"属性,不让布局延伸到状态栏,这时状态栏就是透明的,然后添加一个和状态栏高、宽相同的指定颜色View来覆盖被透明化的状态栏。

  • 创建View并添加到状态栏

使用步骤

一、项目组织结构图

注意事项:

  • 导入类文件后需要change包名以及重新import R文件路径
  • values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、使用方法

修改valus目录下的styles.xml文件

<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

    <!-- Android 状态栏着色 -->
    <style name="TranslucentTheme" parent="AppTheme">
    </style>

</resources>

添加\修改values-v19目录下的styles.xml文件

<resources>

    <!--
        Base application theme for API 19+. This theme completely replaces
        AppBaseTheme from BOTH res/values/styles.xml and
        res/values-v11/styles.xml on API 19+ devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
        <!-- API 19 theme customizations can go here. -->
    </style>

    <!-- Android 状态栏着色 -->
    <style name="TranslucentTheme" parent="AppTheme">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">false</item>
    </style>

</resources>

添加\修改values-v21目录下的styles.xml文件

<resources>

    <!--
        Base application theme for API 21+. This theme completely replaces
        AppBaseTheme from BOTH res/values/styles.xml and
        res/values-v11/styles.xml on API 21+ devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
        <!-- API 21 theme customizations can go here. -->
    </style>

    <!-- Android 状态栏着色 -->
    <style name="TranslucentTheme" parent="AppTheme">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">false</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

</resources>

在values目录下的colors.xml文件中添加状态栏着色的颜色值代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Android 状态栏着色 -->
    <color name="colorPrimary">#0164C5</color>
</resources>

在AndroidManifest.xml中给Application设置TranslucentTheme主题

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.why.project.statusbarcolor">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/TranslucentTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

在activity布局文件中的根节点元素中添加android:fitsSystemWindows="true"

<?xml version="1.0" encoding="utf-8"?>
<!-- Android 状态栏着色:android:fitsSystemWindows="true" -->
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.why.project.statusbarcolor.MainActivity"
    android:fitsSystemWindows="true">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:text="Hello World!"
        android:textColor="#ffffff"
        android:background="@color/colorPrimary"
        android:gravity="center"/>
</RelativeLayout>

在Activity类中添加以下红色标记的代码


package com.why.project.statusbarcolor;

import android.app.Activity;import android.content.Context;import android.os.Build;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;

public class MainActivity extends Activity {

   @Override   protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_main);

      /*==========Android 状态栏着色=============*/      addStatusBarView();   }

   /*==========Android 状态栏着色=============*/   private void addStatusBarView() {      int height;      height = getStatusBarHeight(this);      if (height <= 0) {         return;      }      View view = new View(this);      view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);      ViewGroup decorView = (ViewGroup) findViewById(android.R.id.content);      decorView.addView(view, params);   }

   /**    * 获取状态栏的高度    * 19API以上 读取到状态栏高度才有意义    */   private int getStatusBarHeight(Context context) {      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {         int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");         return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0;      } else {         return 0;      }   }

}

注意:

  • Android studio新建的项目默认extends AppCompatActivity !此处需要修改为extends Activity或者FragemntActivity或者自定义的activity基类。
  • 如果activity布局中含有fragment布局,那么在Activity含有以上代码的基础上只需要在fragment布局文件中添加上android:fitsSystemWindows="true"即可

混淆配置

参考资料

Android 状态栏着色实践

http://www.jianshu.com/p/bae25b5eb867

Android开发-状态栏着色原理和API版本兼容处理

http://blog.csdn.net/card361401376/article/details/61420830

项目demo下载地址

链接:http://pan.baidu.com/s/1i4EtROp 密码:twrf

时间: 2024-11-10 00:01:45

Android状态栏着色的相关文章

Android开发-状态栏着色原理和API版本兼容处理

介绍 先上实际效果图,有三个版本请注意区分API版本 API>=20 API=19 API<19 以上的效果我们称之为对状态栏的着色,而非沉浸式状态栏,那是另外的东西. 想要实现以上的效果并不难,阅读本文了解原理后,就会觉得想要以上的效果真的很简单. 本文旨在总结我的理解告诉读者一步步实现状态栏着色的原理. 原理 第一步-设置透明状态栏 对状态栏的控制一切基础都源于 static public void setTranslucentWindows(Activity activity) { if

Android 透明状态栏&amp;着色状态栏

Android 5.0 及以上实现方式(android在5.0之后引入Material Design 实现方式相对简单) 透明状态栏,背景浸入状态栏 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } 在布局文件中View 默认f

Android开发-状态栏着色原理和API版本号兼容处理

介绍 先上实际效果图,有三个版本号请注意区分API版本号 API>=20 API=19 API<19 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ2FyZDM2MTQwMTM3Ng==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=" 以上的效果我们称之为对状态栏的着色,而非沉浸式状态栏.那是另外的东西. 想要实现

获取Android状态栏高度的屡试不爽的方法

如下代码所示: [java] view plaincopy private int getStatusBarHeight() { Class<?> c = null; Object obj = null; Field field = null; int x = 0, sbar = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getFi

Android状态栏透明(沉浸式效果)

Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q4878802/9058275 1. 修改状态栏和导航栏的属性为透明 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //透明状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_T

android 状态栏操作

最近太忙了.好长时间没动博客,把原来的东西拿出来都重新温习下. private void collapseStatusBar() { int currentApiVersion = android.os.Build.VERSION.SDK_INT; try { Object service = getSystemService("statusbar"); Class<?> statusbarManager = Class .forName("android.app

android状态栏总结

针对状态栏的操作,只针对4.4kitKat(含)以上的机型,部分国产rom会失效,目前发现的有华为的EMUI Activity必须是noActionbar主题 本文基于StatusBarUtils略作修改,感谢作者laobie 本文源码地址 相关属性重温 FitsSystemWindows在使用FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS.FLAG_TRANSLUCENT_STATUS挤占了状态栏的高度的时候,我们的布局文件也跟着顶到了状态栏上.通过FitsSystemWi

android 状态栏(StatusBar)

一.SystemUI 概述 自 android2.2 开始 , 原本存在与 framework-res.apk 中的状态栏和下拉通知栏界面控制被分割出一个单独的 apk 文件 , 命名为 SystemUI.apk, 保存在 System/app 文件夹中.在 SystemUI.apk 中 , 是存在着状态栏的图标 ,XML 和控制文件等 , 这样的分割 , 使我们可以更方便地去修改. SystemUI 模块中主要包含了 USB 和 Statusbar 两个子模块,本文将以 Statusbar 为

Android -- 状态栏高度

干货 Class<?> c = null; Object obj = null; Field field = null; int x = 0, sbar = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field