Android 5.0 如何實現將布局的內容延伸到狀態欄?
Android自5.0以後,應用可以實現類似iOS的狀態欄變色功能,類似Android版的知乎。這種實現方式很簡單,只需要在style裡面指定顏色即可。
但是類似Google play的將布局的內容延伸到狀態欄實一直沒有找到辦法,如圖 這個頂部狀態欄。一半是這張圖片。一半是綠色。嘗試吧狀態欄設為透明。結果。。它真透明了。沒顏色了 大神們說說這個是如何實現的呢?需要特別的辦法嗎。之前放了兩張圖可能讓大家有了誤會
不請自來,我覺得有些回答說的不是很完整,局限比較多。這個問題昨天正好研究了下,我的拙見是:如果不需要支持 4.4,建議使用 statusBarColor如果需要支持 4.4,簡易 4.4 使用 windowTranslucentStatus;5.x 使用 statusBarColor/colorPrimaryDark(本答案在 5.1 和 5.0 中的解決方式並不會影響軟鍵盤和 EditText 的行為,4.4 暫時無法測試,如有朋友發現 bug 請指出,我會在回答中註明,以免其他人一起掉坑裡)下面說原因:
所以簡易重寫 v21 的 style,只將 windowTranslucnetStatus 應用於 v19。而 v21 使用 statusBarColor 自定義符合設計指南的顏色。Toolbars and status bars
Toolbars and larger color blocks should use the 500 color of the primary color of your app. The status bar should be the darker 700 tint of your primary color.
getWindow().setStatusBarColor()
設置半透明 statusbar
2.getWindow()
.getDecorView()
.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
因為 FLAT_LAYOUT_STABLE 和 FLAG_LAYOUT_FULLSCREEN 是伴隨 translucentStatus 自動設置的,v21 上你需要手動設置(因為上述方法沒用 translucentStatus)。
3. 手動調整各個 View 的位置:可以動態或缺 StatusBar 的 Height。也可以像我一樣比較懶惰&
未來的 Android M (感謝 @張啟 指正)
values-v23/dimens.xml&
為啥那麼麻煩問 Google 去。
4. Enjoyv19:v21:個人感覺排名第一的答案將簡單問題複雜化了,其實Google在最新(截止2015年6月)的suport包已經提供了很好的支持。
UPDATED....
有圖有真相,以下截圖和題主描述完全一致:&
&
&
截圖中的Activity使用DrawerLayoutTheme,以使得Drawer能顯示在半透明的狀態欄內。
第2步
DrawerLayout的drawer部分的根布局寫成ScrimInsetsFrameLayout(android.support.design.internal.ScrimInsetsFrameLayout,在design支持包中,繼承於FrameLayout,代碼也很簡單,但貌似是hide的,從源碼複製一份出來就好了),或者直接用更規範的NavigationView(android.support.design.widget.NavigationView,NavigationView也直接繼承於ScrimInsetsFrameLayout)
這2步完了就實現了題主所說的效果(也是截圖中的效果)。
附上截圖中Activity的布局:
&
&
&
&
&
&
&
&
&
&
UPDATE:
題主修改了問題,我來更新一下:
想要讓布局延伸到 System bar 的下方,最直接的方法就是設置 windowTranslucentStatus/Navigation="true"。
簡單粗暴,但是會帶來三個問題:
1. 你需要手動添加 Status bar 的空間,設置一個 25 dp 的 View 在布局頂部就能搞定;
2. 狀態欄顏色不符合 Material design Guideline 的要求,不過你可以在 PS 什麼的裡面畫一個顏色為黑色、透明度為 40% 的矩形,然後在這個矩形下面畫另一個矩形,調整它的顏色使得兩個矩形疊加部分的顏色剛好是 700,最後把剛剛的那個 View 的顏色設置成一樣的就可以了;3. 即使使用了 adjustResize,軟鍵盤也會擋住 EditText。這是一個令人極度痛苦的問題,解決方法之一是在根布局設置 fitsSystemWindow="true",然並卵,原答案解釋過了;二是使用下面這個類:madebycm/AndroidBug5497Workaround · GitHub。
重要提醒:建議題主只設置 windowTranslucentStatus,不要同時設置 Navigation。一旦同時啟用了這兩個屬性,那麼上面問題 3 的解決方案就無效了。而且據我所知,問題 3 就會升級成完全沒有解決方案了,因為這是一個在 Android 1.5 就存在的 bug,至今也沒能解決(戳這裡:Issue 5497 -
android -
WebView adjustResize windowSoftInputMode breaks when activity is fullscreen;儘管問題 3 的解決方案名字就叫 5497Workaround,但是經我測試,它只能解決在 translucentStatus 下 adjustResize 無用的問題)。
P.S 我測試了樓下 @Allan 的回答,發現更好的方式是設置 statusBarColor 為全透明,然後再在布局文件添加顏色為 700、高度為 25dp 的 View 作為狀態欄(嗯,這樣可以避免在 PS 里找出正確的狀態欄 View 顏色的問題)。同時他採取了在 Activity 里設置 window flag 的形式,那個 fullscreen 的 flag 在我的測試里已經對 adjustResize 產生了影響,但是不知道問題 3 的解決方案能否生效(如果有人測試了,請告訴我答案);除此之外,@Allan 的做法是不會讓導航欄變成透明的。
完畢。
----------------------------------------我是萌萌的分割線----------------------------------------
原答案:
反對原排名第一的答主。
同時設置 windowTranslucentStatus="true" 和 fitsSystemWindow="true" ,結果會是什麼樣子的呢?請參見提問描述:Android 5.0及以上如何在Translucent模式下防止鍵盤擋住EditText? - Android 開發
fitsSystemWindow="true" 會使得屏幕上的可布局空間位於狀態欄下方與導航欄上方。這兩條欄你可以設置它的顏色(5.0 及以上,使用 statusBarColor 等),可以設置它透明(4.4及以上,使用 windowTranslucent ),但是你布局裡的內容無法伸展到它們所在的位置,因此,再同時設置 windowTranslucentStatus/Navigation 就沒有了意義,因為這兩個屬性的作用就是讓內容得以延伸到狀態欄和導航欄所在的空間,形成類似全屏的視覺效果(事實上,這兩個屬性同時設置的話,就相當於給 window 設置了全屏的 flag)。
題主提問中, Google Play 的 drawer 之所以在狀態欄中也能夠顯示的原因是因為它使用了 ScrimInsetsFrameLayout,Google 最新的 support-design 包里的 NavigationView 正是繼承自該 Layout。這個 Layout 重寫了 onApplyWindowInsets 方法,能夠獲取狀態欄和導航欄的大小,在 onDraw 方法中調整畫布以去除它們,從而讓自身的內容可以全屏顯示。
題主若想實現同樣的 Drawer,使用 NavigationView 即可。不必設置 windowTranslucentStatus/Navigation 就能夠達到 Material design 里規範的 drawer 的顯示效果,只需要在你的 styles-v21.xml 裡面這麼寫:
&
&
然後遵循 NavigationView 的寫法,在 DrawerLayout 中加入 fitsSystemWindow="true" 就可以了。對於 Actionbar,可以在 DrawerLayout 里添加一個 Toolbar,將其設置為 Actionbar,那麼它也不會跑到狀態欄裡面去了。
值得注意的還有,假如你想有一個全屏的動畫之類的全屏效果,那麼該動畫對應的 View 不能處於設置了 fitsSystemWindow 為 true 的布局內,除非該布局也是 ScrimInsetsFrameLayout。
以上變色的話直接調Activity.setStatusBarColor就行,透明的話參考@1ittlecup提供的方法。
在 styles.xml 里:
&
這個的實質是 4.x 風格的狀態欄半透明。它會把狀態欄那一塊先蒙上一層半透明的灰色(#66000000)遮罩,再和主要試圖區域連在一起,扔給你的 activity。故而你的 actionBar 會上挪到屏幕頂部,修正的方法是在布局 xml 的 root 節點裡加入:
android:fitsSystemWindows="true"
即可。
如果布局比較複雜的話,簡單的 fitsSystemWindows 也許就不能應付需求了,若需要手工計算頂欄(statusBar)的高度,送人送到底我還是貼出來吧: public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId &> 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
PS:對應的底部虛擬按鍵是 android:windowTranslucentNavigation。
安卓4.4以上的新特性,沉浸式菜單欄,可以去了解下
官方源碼處理這個問題的代碼在哪裡,大神們能講解下源碼嗎,百度一堆都是別人說怎麼做怎麼做,效果並不是很好,大神能解讀一下源碼嗎
我也總結了下,無論你是想要md效果還是沉浸式效果都比較簡單,歡迎找bug
狀態欄變色 - litefish的專欄style分三種情況來寫,通用,19,21
styles.xml
``` xml
&&
```v19 styles.xml``` xml
& ```v21 styles.xml``` xml & ```我寫的一點總結:http://codpoe.me/2016/08/08/translucent-statusbar/
在原生 Android 上測試沒問題,而在某些國產 ROM 上,例如 Smartisan OS,就會顯示為全透明了,沒有 MD 規範的半透明效果,而且也沒有 colorPrimaryDark 的效果。有個開源項目叫systembar好像,支持此類
問題來了,我一直想知道谷歌地圖和騰訊的地圖的透明度為什麼有區別,見圖:谷歌地圖騰訊地圖
安卓5.0的特色就是這樣,代碼不是太懂,但是設置裡面很能反映修改的內容:仿安卓5.0UI下載
推薦閱讀:
※最近Android studio出了1.0版,但是SDK一直無法下載,請問大家是怎麼解決的?
※如何成為 Android 開發高手?
※sdk manager更新失敗,顯示Download interrupted: read timed out,應該如何解決?
※Vivo Xplay5要配備6G內存。Android系統真的需要這麼大的內存嗎?
※達到什麼技術水平的 Android 或 iOS 開發者算高手?
TAG:Android應用 | Android開發 | GooglePlay | Android | AndroidL |