Android 4.4以上"沉浸式"狀態(tài)欄效果的實(shí)現(xiàn)方法
什么是沉浸式狀態(tài)欄?
沉浸式狀態(tài)欄意思指狀態(tài)欄的顏色隨著軟件顏色而改變,使?fàn)顟B(tài)欄和軟件顏色保持一致,沉浸其中!當(dāng)我們打開(kāi)應(yīng)用程序時(shí),不會(huì)再因?yàn)榭吹綉?yīng)用程序和狀態(tài)欄的黑邊相隔開(kāi)而感到十分難看。沉浸式狀態(tài)欄由于其能給用戶群體帶來(lái)極佳的用戶體驗(yàn),已經(jīng)在越來(lái)越多的應(yīng)用上得到了體現(xiàn)。
實(shí)現(xiàn)原理
從4.4后系統(tǒng)增加了透明狀態(tài)欄的特性WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
一旦添加上這個(gè)屬性后,那么布局中的內(nèi)容
DecorView
就會(huì)自動(dòng)填充到狀態(tài)欄。所有的實(shí)現(xiàn)都是基于這個(gè)特性,就相當(dāng)于這個(gè)時(shí)候狀態(tài)欄會(huì)默認(rèn)空出來(lái),然后開(kāi)發(fā)者可以自定義view來(lái)填充這個(gè)高度的.
實(shí)現(xiàn)的過(guò)程中可能還要用到android:fitsSystemWindows="true"
,這個(gè)屬性很重要。其含義:view可以根據(jù)系統(tǒng)窗口(如status bar,軟鍵盤)來(lái)調(diào)整自己的布局,如果值為true,就會(huì)調(diào)整view的paingding
屬性來(lái)給system windows留出空間....
那么現(xiàn)在來(lái)看看具體實(shí)現(xiàn)方式吧
一般頁(yè)面都是自己定義個(gè)類標(biāo)題欄
實(shí)現(xiàn)
從實(shí)現(xiàn)效果上,這里大致分為兩種
1、單獨(dú)給狀態(tài)欄著色
使用這個(gè)開(kāi)源庫(kù)SystemBarTint
/** * 狀態(tài)欄顏色設(shè)置方法 * @param context * @param color */ public static void smartTintManager(Activity context, int color){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = context.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 創(chuàng)建狀態(tài)欄的管理實(shí)例 SystemBarTintManager tintManager = new SystemBarTintManager(context); // 激活狀態(tài)欄設(shè)置 tintManager.setStatusBarTintEnabled(true); tintManager.setStatusBarTintColor(color); } }
在對(duì)應(yīng)的頁(yè)面的根布局中添加android:fitsSystemWindows="true"
,且根布局中不能設(shè)置整體的大背景色,否則狀態(tài)欄著色就會(huì)被覆蓋
調(diào)用上面方法設(shè)置具體的顏色(依據(jù)開(kāi)源庫(kù),其中就一個(gè)核心類,可以直接把那個(gè)類拷貝到項(xiàng)目中)
這里主要講一下具體的實(shí)現(xiàn)原理
private void setupStatusBarView(Context context, ViewGroup decorViewGroup) { mStatusBarTintView = new View(context); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight()); params.gravity = Gravity.TOP; if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) { params.rightMargin = mConfig.getNavigationBarWidth(); } mStatusBarTintView.setLayoutParams(params); mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR); mStatusBarTintView.setVisibility(View.GONE); decorViewGroup.addView(mStatusBarTintView); }
通過(guò)這段代碼,很容易看出,通過(guò)動(dòng)態(tài)生成一個(gè)view,然后這個(gè)view寬是MATCH_PARENT
, 高度是系統(tǒng)狀態(tài)欄的高度;然后為這個(gè)動(dòng)態(tài)生成的view設(shè)置一個(gè)背景顏色;最后將這個(gè)view添加到decorViewGroup
這個(gè)view容器中,那再看看這個(gè)view到底是誰(shuí)
/** * Constructor. Call this in the host activity onCreate method after its * content view has been set. You should always create new instances when * the host activity is recreated. * * @param activity The host activity. */ @TargetApi(19) public SystemBarTintManager(Activity activity) { Window win = activity.getWindow(); //獲得DecorView根布局容器 ViewGroup decorViewGroup = (ViewGroup) win.getDecorView(); ..... if (mStatusBarAvailable) { // 這個(gè)view容器是decorViewGroup setupStatusBarView(activity, decorViewGroup); } if (mNavBarAvailable) { setupNavBarView(activity, decorViewGroup); } }
注意看上面兩個(gè)我手動(dòng)添加的注釋,可見(jiàn),這種做法思想就是狀態(tài)欄透明后,向根布局decorViewGroup
中添加一個(gè)和狀態(tài)欄等高度的view。至于你讓這個(gè)view是什么顏色,那就隨你心情了。
2、用標(biāo)題欄的背景色來(lái)填充狀態(tài)欄
將狀態(tài)欄設(shè)置為半透明的,此時(shí)出現(xiàn)的問(wèn)題是下面的內(nèi)容會(huì)占據(jù)了狀態(tài)欄。
如果我們?cè)赼ctivity的根布局添加 android:fitsSystemWindows="true"
那么此時(shí)狀態(tài)欄還是可以看見(jiàn)的,并沒(méi)有占據(jù)。那這個(gè)屬性的作用就在此了。
此時(shí)我們借助狀態(tài)欄的高度,為下面的內(nèi)容設(shè)置一個(gè)padding-top
距離(因?yàn)闋顟B(tài)欄半透明后,下面的內(nèi)容會(huì)占據(jù)原有的狀態(tài)欄,那么將其設(shè)置一個(gè)padding
的狀態(tài)欄高度即可)這樣設(shè)置后,在這個(gè)view的背景的padding
下,原有的狀態(tài)欄高度填充了同樣的背景色,那么這樣的話就貌似所謂的沉浸式了
這種方式說(shuō)白了,就是狀態(tài)欄半透明后,用下面的內(nèi)容來(lái)合適的填充(因?yàn)槟J(rèn)半透明會(huì)是被占據(jù))
代碼如下:
@SuppressLint("InlinedApi") public static void setImmerseLayout(Activity context, View view) { if (context == null || view == null) { return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = context.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); int statusBarHeight = getStatusBarHeight(context.getBaseContext()); view.setPadding(0, statusBarHeight, 0, 0); } } /** * 用于獲取狀態(tài)欄的高度。 使用Resource對(duì)象獲取(推薦這種方式) * * @return 返回狀態(tài)欄高度的像素值。 */ 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; }
對(duì)這個(gè)view設(shè)置一個(gè)padding_top
,而這個(gè)padding
的距離剛好是狀態(tài)欄的高度,那么這個(gè)view的背景就填充到了狀態(tài)欄了。
值得注意的是:這個(gè)標(biāo)題欄的高度一定要是wrap_content
,因?yàn)槿绻蔷唧w的高度,然后在設(shè)置個(gè)paddingtop
的話,那么就會(huì)把部分標(biāo)題欄的內(nèi)容擠出去了,不完整了。
所以通常的做法是將原有的標(biāo)題欄外面在嵌套一個(gè)<FrameLayout />
,然后將標(biāo)題欄背景設(shè)置成<FrameLayout />
的背景色
<FrameLayout android:id="@+id/title" android:layout_width="match_parent" android:background="@color/common_theme_color" android:layout_height="wrap_content">
總結(jié)
關(guān)于沉浸式效果的實(shí)現(xiàn)方式就到這了,希望這篇文章的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家也可以留言交流。
- Android 實(shí)現(xiàn)沉浸式狀態(tài)欄的方法
- Android 沉浸式狀態(tài)欄與隱藏導(dǎo)航欄實(shí)例詳解
- 解決Android 沉浸式狀態(tài)欄和華為虛擬按鍵沖突問(wèn)題
- Android之沉浸式狀態(tài)欄的實(shí)現(xiàn)方法、狀態(tài)欄透明
- Android沉浸式狀態(tài)欄微技巧(帶你真正理解沉浸式模式)
- Android App仿QQ制作Material Design風(fēng)格沉浸式狀態(tài)欄
- Android編程中沉浸式狀態(tài)欄的三種實(shí)現(xiàn)方式詳解
- Android 高仿QQ 沉浸式狀態(tài)欄
- 另外兩種Android沉浸式狀態(tài)欄實(shí)現(xiàn)思路
- Android實(shí)現(xiàn)沉浸式狀態(tài)欄功能
相關(guān)文章
Android仿微信聯(lián)系人列表字母?jìng)?cè)滑控件
這篇文章主要為大家詳細(xì)介紹了Android仿微信聯(lián)系人列表字母?jìng)?cè)滑控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Android使用Sensor感應(yīng)器實(shí)現(xiàn)線程中刷新UI創(chuàng)建android測(cè)力計(jì)的功能
這篇文章主要介紹了Android使用Sensor感應(yīng)器實(shí)現(xiàn)線程中刷新UI創(chuàng)建android測(cè)力計(jì)的功能,實(shí)例分析了Android使用Sensor感應(yīng)器實(shí)現(xiàn)UI刷新及創(chuàng)建測(cè)力器的技巧,需要的朋友可以參考下2015-12-12Android界面設(shè)計(jì)(APP設(shè)計(jì)趨勢(shì) 左側(cè)隱藏菜單右邊顯示content)
這文章講述了2013年未來(lái)的移動(dòng)APP設(shè)計(jì)趨勢(shì),感覺(jué)挺有道理的:Android界面設(shè)計(jì)實(shí)現(xiàn)左側(cè)隱藏菜單右邊顯示content,感興趣的你可以了解下啊,希望本文對(duì)你的APP設(shè)計(jì)提高有所幫助哦2013-01-01Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例
下面小編就為大家分享一篇Android自定義processor實(shí)現(xiàn)bindView功能的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android動(dòng)態(tài)添加view的方法示例
本篇文章主要介紹了Android動(dòng)態(tài)添加view的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10全面解析Android的開(kāi)源圖片框架Universal-Image-Loader
這篇文章主要介紹了Android的開(kāi)源圖片框架Universal-Image-Loader,Universal-Image-Loader在GitHub上開(kāi)源,其提供的圖片加載功能令人印象相當(dāng)深刻,需要的朋友可以參考下2016-04-04