1. 程式人生 > >安卓高階9 沉浸式佈局 獲取狀態列高度等

安卓高階9 沉浸式佈局 獲取狀態列高度等

Android 沉浸式狀態列、狀態列一體化、透明狀態列、仿iOS透明狀態列 

http://blog.csdn.NET/jdsjlzx/article/details/50437779

注:狀態列的字型顏色位白色, 如果狀態列背景為白色,上面的部落格已經解決了。

最近業務上看到一個設計圖挺好看,所以研究了一下透明狀態列,注意不是沉浸式狀態列,在參考了網上的一些資料後,整理出了這篇部落格.

參考文章:
全屏( ContentView 可以進入狀態列)非全屏 ( ContentView 與狀態列分離, 狀態列直接著色)

先定義幾個名詞:

  1. 全屏模式: 左邊圖所示.

  2. 著色模式: 右邊圖所示.

  3. ContentView: activity.findViewById(Window.ID_ANDROID_CONTENT) 獲取的 View , 即 setContentView 方法所設定的 View

    的父佈局,FrameLayout.

  4. ContentParent: ContentView 的 parent , 實質為 LinearLayout.

  5. ChildView: ContentView 的第一個子 View ,即佈局檔案中的 layout .

再介紹一下相關的函式:

  1. fitsSystemWindows, 該屬性可以設定是否為系統 View 預留出空間, 當設定為 true 時,會預留出狀態列的空間.

  2. ContentView, 實質為 ContentFrameLayout, 但是重寫了 dispatchFitSystemWindows 方法, 所以對其設定 fitsSystemWindows 無效.

  3. ContentParent, 實質為 FitWindowsLinearLayout, 裡面第一個 View 是 ViewStubCompat, 如果主題沒有設定 title ,它就不會 inflate .第二個 View 就是 ContentView.

5.0以上的處理:

自5.0引入 Material Design ,狀態列對開發者更加直接,可以直接呼叫 setStatusBarColor 來設定狀態列的顏色.

全屏模式:

  1. Window window = activity.getWindow();  
  2. //設定透明狀態列,這樣才能讓 ContentView 向上
  3. window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);   
  4. //需要設定這個 flag 才能呼叫 setStatusBarColor 來設定狀態列顏色
  5. window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);   
  6. //設定狀態列顏色
  7. window.setStatusBarColor(statusColor);  
  8. ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);  
  9. View mChildView = mContentView.getChildAt(0);  
  10. if (mChildView != null) {  
  11.     //注意不是設定 ContentView 的 FitsSystemWindows, 而是設定 ContentView 的第一個子 View . 使其不為系統 View 預留空間.
  12.     ViewCompat.setFitsSystemWindows(mChildView, false);  
  13. }  

著色模式:

  1. Window window = activity.getWindow();  
  2. //取消設定透明狀態列,使 ContentView 內容不再覆蓋狀態列
  3. window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);   
  4. //需要設定這個 flag 才能呼叫 setStatusBarColor 來設定狀態列顏色
  5. window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);   
  6. //設定狀態列顏色
  7. window.setStatusBarColor(statusColor);  
  8. ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);  
  9. View mChildView = mContentView.getChildAt(0);  
  10. if (mChildView != null) {  
  11.     //注意不是設定 ContentView 的 FitsSystemWindows, 而是設定 ContentView 的第一個子 View . 預留出系統 View 的空間.
  12.     ViewCompat.setFitsSystemWindows(mChildView, true);  
  13. }  

4.4-5.0的處理:

4.4-5.0因為沒有直接的 API 可以呼叫,需要自己相容處理,網上的解決方法基本都是建立一下高度為狀態列的 View ,通過設定這個 View 的背景色來模擬狀態列. 這裡我嘗試了三種方法來相容處理.

方法1: 向 ContentView 新增假 View , 設定 ChildView 的 marginTop 屬性來模擬 fitsSystemWindows .

全屏模式:

  1. Window window = activity.getWindow();  
  2. ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);  
  3. //首先使 ChildView 不預留空間
  4. View mChildView = mContentView.getChildAt(0);  
  5. if (mChildView != null) {  
  6.     ViewCompat.setFitsSystemWindows(mChildView, false);  
  7. }  
  8. int statusBarHeight = getStatusBarHeight(activity);  
  9. //需要設定這個 flag 才能設定狀態列
  10. window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  
  11. //避免多次呼叫該方法時,多次移除了 View
  12. if (mChildView != null && mChildView.getLayoutParams() != null && mChildView.getLayoutParams().height == statusBarHeight) {  
  13.     //移除假的 View.
  14.     mContentView.removeView(mChildView);  
  15.     mChildView = mContentView.getChildAt(0);  
  16. }  
  17. if (mChildView != null) {  
  18.     FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mChildView.getLayoutParams();  
  19.     //清除 ChildView 的 marginTop 屬性
  20.     if (lp != null && lp.topMargin >= statusBarHeight) {  
  21.         lp.topMargin -= statusBarHeight;  
  22.         mChildView.setLayoutParams(lp);  
  23.     }  
  24. }  

著色模式:

  1. Window window = activity.getWindow();  
  2. ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);  
  3. //First translucent status bar.
  4. window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  
  5. int statusBarHeight = getStatusBarHeight(activity);  
  6. View mChildView = mContentView.getChildAt(0);  
  7. if (mChildView != null) {  
  8.     FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mChildView.getLayoutParams();  
  9.     //如果已經為 ChildView 設定過了 marginTop, 再次呼叫時直接跳過
  10.     if (lp != null && lp.topMargin < statusBarHeight && lp.height != statusBarHeight) {  
  11.         //不預留系統空間
  12.         ViewCompat.setFitsSystemWindows(mChildView, false);   
  13.         lp.topMargin += statusBarHeight;  
  14.         mChildView.setLayoutParams(lp);  
  15.     }  
  16. }  
  17. View statusBarView = mContentView.getChildAt(0);  
  18. if (statusBarView != null && statusBarView.getLayoutParams() != null && statusBarView.getLayoutParams().height == statusBarHeight) {  
  19.     //避免重複呼叫時多次新增 View
  20.     statusBarView.setBackgroundColor(statusColor);  
  21.     return;  
  22. }  
  23. statusBarView = new View(activity);  
  24. ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);  
  25. statusBarView.setBackgroundColor(statusColor);  
  26. //向 ContentView 中新增假 View
  27. mContentView.addView(statusBarView, 0, lp);  

方法2: 向 ContentParent 新增假 View ,設定 ContentView 和 ChildView 的 fitsSystemWindows.

全屏模式:

  1. Window window = activity.getWindow();  
  2. window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  
  3. ViewGroup mContentView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);  
  4. ViewGroup mContentParent = (ViewGroup) mContentView.getParent();  
  5. View statusBarView = mContentParent.getChildAt(0);  
  6. if (statusBarView != null && statusBarView.getLayoutParams() != null && statusBarView.getLayoutParams().height == getStatusBarHeight(activity)) {  
  7. 相關推薦

    高階9 沉浸佈局 獲取狀態高度

    Android 沉浸式狀態列、狀態列一體化、透明狀態列、仿iOS透明狀態列 http://blog.csdn.NET/jdsjlzx/article/details/50437779注:狀態列的字型顏色位白色, 如果狀態列背景為白色,上面的部落格已經解決了。最近業務上看到一個設計圖挺好看,所以研究了一下透明狀

    中使用流佈局實現標籤

    我們在開發的時候通常需要加標籤,對於這個標籤怎麼說呢,反正也挺複雜的,最初開發這個標籤的時候還是沒有思路的,後來在github上面查找了一下資料,瞭解了通過流式佈局來實現這個標籤,我記得開始的時候我寫標籤的時候是三個TextView一個一個新增進去的,後來感覺還是不太好,所

    如何設定沉浸狀態,注意處理華為有虛擬按鍵的問題

    當前安卓開發中,基本都使用了沉浸時候狀態列,拉伸視覺體驗,增大了螢幕空間,但是如何設定沉浸式狀態列呢,這裡簡單進行介紹: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { activity

    【Android】狀態相關適配(判斷MIUI,Flyme,狀態圖示顏色切換,獲取狀態高度沉浸狀態相關

    對於狀態列相關適配這個事情,真是讓人頭疼的一個模組。因為負責的專案主題色偏偏是白色,不但要去適配 MIUI ,Flyme(因為這兩個都可以實現沉浸式,並且圖示可以切換成黑色),也要分別適配 Android 6.0 以下, Android 6.0 起兩種不同情況(6.0 起原

    4.3,原始碼內隱藏狀態,導航欄

    博主使用的是天嵌的IMX6Q 安卓版本4.3 修改方法: 導航欄:     修改 build/tools/buildinfo.sh 58行         echo "qemu.hw.mainkey

    仿京東首頁沉浸圖片以及狀態變色

    這個效果搞了三個小時,有一種淡淡的憂傷 先看下效果 網上這方面的案例特別的少 思路很重要,說下實現的過程: step1:  佈局什麼的就不說了,首先在Mainactivity實現沉浸式狀態列 public static void setWindowImm

    Andorid獲取狀態高度的三種方法

    轉載請註明出處 今天正好做專案需要用到狀態列高度,我用的就是下面的第三種方法,沒有成功,換成第一種方法果斷解決。 在應用開發中,有時我們需要用程式碼計算佈局的高度,可能需要減去狀態列(status bar)的高度。狀態列高度定義在Android系統尺寸資源中status_bar_he

    android 程式碼獲取狀態高度

    專案中有需求要獲取到狀態列的高度, 故記錄一下程式碼的實現 /** * 利用反射獲取狀態列高度 * @return */ public int getStatusBarHeight() { int result = 0; //獲取狀態列高度的資源id int resource

    popupwindow全螢幕顯示被狀態擋住如何解決+Android獲取狀態高度

    這是我在開發app中的篩選需求,使用popupwindow顯示篩選panel,在我的Android4.2系統中顯示效果,popupwindow被狀態列statusBar擋住。 需求中這個篩選的介

    Andorid獲取狀態高度

    在應用開發中,有時我們需要用程式碼計算佈局的高度,可能需要減去狀態列(status bar)的高度。狀態列高度定義在Android系統尺寸資源中status_bar_height,但這並不是公開可直接使用的,例如像通常使用系統資源那樣android.R.dimen.sta

    Android完美獲取狀態高度、標題欄高度、編輯區域高度獲取

            日常開發中我們經常會因為繪圖、繪製自定義元件、定位元件或者是計算佈局高度需要減去狀態列高度等需要來獲取Activity介面中狀態列、標題欄的高度。但很多人馬上要拿起來就用還是會遇到各種

    Android 獲取狀態高度

    在原始碼程式中程式碼: height= getResources().getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); 通過SDK獲取程式碼: //獲取狀態列高度   Class

    Android獲取狀態高度,動態設定控制元件高度

    獲取狀態列高度//獲取status_bar_height資源的ID int resourceId = getResources().getIdentifier("status_bar_height",

    入門系列-05常見佈局之RelaiveLayout(相對佈局

    接著上一篇提到的線性佈局,如果說線性佈局是遵循一種順序排放,一處存在一個元件就不會存在另一個。那麼相對佈局則是位置上的相對關係(對於其他元件),不指定相對位置則會堆在一起重疊起來。 1.什麼是相對佈局 相對佈局指的是有參照的佈局方式,就是以某個兄弟元件,或者父容器來決定元

    LinearLayout、RelativeLayout、GridLayout目前常用的三種佈局

              **LinearLayout、RelativeLayout、GridLayout安卓常用佈局**------------------------------------------

    動畫系列————layout(佈局)動畫

    Layout動畫:android佈局發生變化時的動畫效果(新增、刪除)。使用該動畫可以讓佈局的變化過度的更自然,而不至於太生硬。通常情況我們都會採用動態新增,系統預設不會啟動layout動畫,需要在

    mui打包應用 生成簽名證書 keystore 獲取簽名

    打包安卓應用 hbuilder中直接打包原生安裝包,安卓應用直接用公用證書就行 生成簽名證書 keystore 輸入 keytool 確定是否安裝了 jdk,沒有就自己去下載安裝。 安裝之後,在命令列直接輸入 keytool -genkey

    Android 修改狀態沉浸佈局總結

    不多說獻上工具類。package com.yazhi1992.practice.immersion_status_bar; import android.app.Activity; import android.content.Context; import android

    筆記之隱啟動Activity篇

    <span style="color:#333333;"> <activity android:name="BrowserActivity" android:label="@string/application_name"

    解決h5手機軟鍵盤彈起佈局壓縮變形

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://