最近在接手一個項目,須要在舊的代碼基礎上添加沉浸式通知欄。所以這段時間專門研究了一下網上已有的例子,發現不太適用當前項目,主要緣由是當前項目不一樣的頁面頂部標題欄的顏色不同,特別是我的中心頁面能夠切換皮膚,而網上的例子大 部分沒考慮到這種狀況。通過多方面考慮,決定本身動手寫。 java
所謂的沉浸式通知欄就是把用來導航的各類界面操做空間隱藏在以程序內容爲主的情景中,經過相對「隱形」的界面來達到把用戶可視範圍最大化地用到內容自己上。而最新安卓4.4系統的通知欄沉浸模式就是在軟件打開的時候通知欄和軟件頂部顏色融爲一體,這樣不只可使軟件和系統自己更加融爲一體。(以下圖所示)android
具體實現方式以下:app
1.新建個公共style,設置android:fitsSystemWindows=trueide
<!-- 設置應用佈局時是否考慮系統窗口布局;true --> <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar"> <item name="android:fitsSystemWindows">true</item> </style>
2. 修改AndroidManifest.xml,讓全部的activity樣式默認設置爲AppBaseTheme(*不一樣項目要靈活處理,筆者項目的activity樣式都是統一的因此這樣設置沒問題,可是實際狀況下不一樣的activity可能調用的樣式不同,須要讀者自行按本身的項目來設置)佈局
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppBaseTheme" android:name="****">
3.新增沉浸式通知欄實現類,實現原理很簡單。ui
1)判斷當前系統版本是否是4.4以上,判斷代碼以下:this
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) spa
2)若是大於4.4則設置狀態欄透明化,代碼以下:code
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); xml
3)獲取activity的根rootView(DecorView),而後建立一個新的view stateBarView並把它添加到rootView(這裏手動給它設置個ID,下次進來時先判斷rootView是否已建立stateBarView,若是已建立則直接獲取該View這樣能夠防止重複建立,致使內存泄露)
如下是具體代碼實現
import android.annotation.SuppressLint; import android.app.Activity; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Build; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.FrameLayout.LayoutParams; /** * 沉浸式通知欄公共類 * @author hurrican * */ @SuppressLint({ "InlinedApi", "ResourceAsColor" }) public class ImmersedNotificationBar { private Activity activity ; //設置沉浸式通知欄的ID(防止重複建立) private final static int IMMERSED_NOTIFICATION_BAR_ID = 12345678 ; private final static String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height" ; public ImmersedNotificationBar(Activity activity){ this.activity = activity ; } //獲取狀態欄高度 private int getStatusBarHeight(Resources res){ int statusBarHeight = 0; int resourceId = res.getIdentifier(STATUS_BAR_HEIGHT_RES_NAME, "dimen", "android"); if (resourceId > 0) { statusBarHeight = res.getDimensionPixelSize(resourceId); } return statusBarHeight ; } //添加頂部狀態欄 private View addStateBar(Activity activity,ViewGroup rootView,int statusBarHeight){ //建立新的View,並添加到rootView頂部) View statusBarView ; if(null!=rootView.findViewById(IMMERSED_NOTIFICATION_BAR_ID)){ statusBarView = rootView.findViewById(IMMERSED_NOTIFICATION_BAR_ID); }else{ statusBarView = new View(activity); rootView.addView(statusBarView); } statusBarView.setId(IMMERSED_NOTIFICATION_BAR_ID) ; LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,statusBarHeight); params.gravity = Gravity.TOP; statusBarView.setLayoutParams(params); statusBarView.setVisibility(View.VISIBLE); return statusBarView ; } /** * 設置狀態欄顏色 * @param ColorId */ public void setStateBarColor(int ColorId){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = activity.getWindow(); //activity的頂級佈局 ViewGroup rootView = (ViewGroup) window.getDecorView(); //透明化狀態欄 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); Resources res = activity.getResources(); //獲取狀態欄目的高度 int statusBarHeight = getStatusBarHeight(res); View stateBarView = addStateBar(activity,rootView,statusBarHeight) ; stateBarView.setBackgroundColor(ColorId) ; } } /** * 設置狀態欄顏色 * @param ColorId */ public void setStateBarDrawable(Drawable drawable){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = activity.getWindow(); //activity的頂級佈局 ViewGroup rootView = (ViewGroup) window.getDecorView(); //透明化狀態欄 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); Resources res = activity.getResources(); //獲取狀態欄目的高度 int statusBarHeight = getStatusBarHeight(res); View stateBarView = addStateBar(activity,rootView,statusBarHeight) ; stateBarView.setBackgroundDrawable(drawable) ; } } }
使用方法很簡單,在onCreate方法裏面建立一個ImmersedNotificationBar對象,而後調用setStateBarColor或setStateBarDrawable方法,由於本人的項目每一個頁面頂部顏色不一致,因此本人是在onResume方法中設置狀態欄顏色,如下是本人項目中的代碼,僅供參考
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.context = this ; initView(); notificationBar = new ImmersedNotificationBar(this) ; } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); notificationBar.setStateBarColor(this.getResources().getColor(R.color.red)) ; }
*文筆很差,有看不明白的能夠留言也能夠發送問題到我郵箱,共同探討,共同進步。本人的郵箱地址是: hurrican_ok@126.com 正常狀況下本人一週至少會登錄一次。若是不能及時回覆請見諒