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
Android狀態欄著色