1. 程式人生 > >Android--›狀態列高度,導航欄高度,Window高度,DecorView高度,heightPixels

Android--›狀態列高度,導航欄高度,Window高度,DecorView高度,heightPixels

喔…這標題,嚇我一跳;

請稍等…

思緒整理中…

Android中, 經常被這些高度絆腳. 完全進入懵逼的狀態, 有木有?

請允許我,介紹清楚!

通常情況下, 寬度都是很友好的,但是高度就呵呵, 所以本文只介紹高度的計算.

2018-10-17更新

安卓開發過程中, 經常被狀態列的高度 導航欄的高度 鍵盤的高度 搞的稀裡糊塗. 經過一段時間整理, 似乎找到了比以前更有效的方法,如下:

所有操作只針對Activity (dialog 不行)window,因為Android介面的載體都是window物件:

可視區域

final View decorView = window.getDecorView
(); Rect outRect = new Rect(); decorView.getWindowVisibleDisplayFrame(outRect); //可視區域 outRect.top -> 可視區域頂部的座標 (也就是狀態列的高度) outRect.bottom -> 可視區域底部的座標 (螢幕高度-導航欄-鍵盤的高度)
public class DecorUtil {

    /**
     * 請勿在dialog中使用
     * <p>
     * 主題的 android:windowTranslucentStatus 屬性, 會影響 contentView 的 padding top.
     * <p>
     * 如果設定了 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN , 那麼 contentView 的 padding top 都是 0
     */
public static void demo(@NonNull final Window window) { final View decorView = window.getDecorView(); int measuredHeight = decorView.getMeasuredHeight(); if (measuredHeight <= 0) { decorView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener
() { @Override public boolean onPreDraw() { decorView.getViewTreeObserver().removeOnPreDrawListener(this); demo(window); return true; } }); } else { Rect outRect = new Rect(); decorView.getWindowVisibleDisplayFrame(outRect); L.w("可視區域:" + outRect); L.w("螢幕高度:" + measuredHeight); if (decorView instanceof ViewGroup) { int childCount = ((ViewGroup) decorView).getChildCount(); if (childCount > 0) { View contentView = ((ViewGroup) decorView).getChildAt(0); L.w("內容高度:" + contentView.getMeasuredHeight() + " p:" + contentView.getPaddingTop()); } if (childCount > 1) { View childView = ((ViewGroup) decorView).getChildAt(1); if (isStatusBar(decorView, childView)) { L.w("狀態列高度:" + childView.getMeasuredHeight()); } else if (isNavigationBar(decorView, childView)) { L.w("導航欄高度:" + childView.getMeasuredHeight()); } else { L.w("未知:" + childView); } } if (childCount > 2) { View childView = ((ViewGroup) decorView).getChildAt(2); if (isStatusBar(decorView, childView)) { L.w("狀態列高度:" + childView.getMeasuredHeight()); } else if (isNavigationBar(decorView, childView)) { L.w("導航欄高度:" + childView.getMeasuredHeight()); } else { L.w("未知:" + childView); } } } } } private static boolean isStatusBar(@NonNull View decorView, @NonNull View childView) { if (childView.getTop() == 0 && childView.getMeasuredWidth() == decorView.getMeasuredWidth() && childView.getBottom() < decorView.getBottom() ) { return true; } return false; } private static boolean isNavigationBar(@NonNull View decorView, @NonNull View childView) { if (childView.getTop() > decorView.getTop() && childView.getMeasuredWidth() == decorView.getMeasuredWidth() && childView.getBottom() == decorView.getBottom() ) { return true; } return false; } }

通過以上方法, 可以獲得:
狀態列高度
導航欄高度以及是否顯示
鍵盤的高度以及是否顯示

已下是舊文

1:DecorView的高度
DecorView的高度代表的是: 整個裝飾視窗的高度, 這個高度包括:狀態爛的高度和導航欄的高度.(狀態列和導航欄通常叫做裝飾視窗, 而ActionBar不屬於裝飾視窗)

這個高度, 可以代表著整個玻璃螢幕的高度.

獲取方式:mActivity.getWindow().getDecorView()

2.Window的RootView的高度
RootView的獲取方式:mActivity.getWindow().findViewById(Window.ID_ANDROID_CONTENT);

這個View對應的高度, 可以表示當前應用程式的有效高度.
在沒有任何修飾的情況下, 應用程式的高度是去掉狀態列和導航欄後的高度;

也就是 (DecorView的高度)-(狀態列的高度)-(導航欄的高度);

但是,如果你使用:
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
這個方法, 那麼RootView的高度會和DecorView的高度相等;

3:heightPixels的高度
heightPixels
這個高度表示…螢幕有效的高度;;;
什麼意思呢?
就是:DecorView的高度去掉導航欄的高度.
這個高度不管你有沒有隱藏導航欄, 這個值都不會改變;

獲取方式:mActivity.getResources().getDisplayMetrics().heightPixels

所以:
番外:如果你想知道你的手機有沒有導航欄:
如果 (DecorView的高度)-(heightPixels) > 0 說明 你的手機有導航欄

番外:如果你想知道你的程式有沒有隱藏導航欄:
情況1:設定了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN屬性:
如果 (RootView的高度)-(heightPixels) > 0 說明 顯示了導航欄

情況2:沒有設定SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN屬性:
如果 (RootView的高度+狀態列的高度)-(heightPixels) > 0 說明 顯示了導航欄

附加1 獲取狀態列的高度
正常情況下: (heightPixels) - (RootView的高度) = 狀態列的高度
但是如果你設定了View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN或者View.SYSTEM_UI_FLAG_HIDE_NAVIGATION屬性的話,這種方法就不準確了.

萬能,100%準確的方法:
getResources().getDimensionPixelSize(getResources().getIdentifier(“status_bar_height”, “dimen”, “android”));

附加2:獲取導航欄的高度
正常情況下: (DecorView的高度) - (heightPixels) = 導航欄的高度
但是如果你設定了View.SYSTEM_UI_FLAG_HIDE_NAVIGATION屬性的話,這種方法就不準確了.

萬能,100%準確的方法:
getResources().getDimensionPixelSize(getResources().getIdentifier(“navigation_bar_height”, “dimen”, “android”));

至此: 文章就結束了,如有疑問: QQ群 Android:274306954 Swift:399799363 歡迎您的加入.

相關推薦

Android狀態導航

1.隱藏狀態列或導航欄 View decordView = getWindow().getDecorView(); /*SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN 分別代表隱藏導航欄和狀態列

獲取狀態導航高度

獲取狀態列高度 public static int getStatusHeight(Context context) { int status_bar_height = 0; int h = context.getResources().getDimensionPixel

iOS狀態導航高度獲取

// 狀態列高度 CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.h

Android 狀態、標題、螢幕高度、全屏

你也可以檢視我的其他同類文章,也會讓你有一定的收貨! 1.獲取狀態列高度: decorView是window中的最頂層view,可以從window中獲取到decorView,然後decorView有個getWindowVisibleDisplayFr

android介面UI美化:沉浸模式、全透明或半透明狀態導航的實現

android api19開始我們就能對頂部狀態列和底部導航欄進行半透明處理了,而api21開始則可以實現全透明狀態列與導航欄以及開啟沉浸模式,至於什麼是沉浸模式,大家百度一下應該就都知道了,有一點需要強調的是全透明不是沉浸模式,前者只是將狀態列、導航欄的背景設定為完全透明,而後者則是完全將狀態列與

Android開發之應用狀態導航都透明

  直接上程式碼 //狀態列、導航欄都透明 private void hideStatusBarNavigationBar() { if (Build.VERSION.SDK_INT = Build.VERSION_CODES.LOLLIPOP)

Android沉浸式狀態導航實現

Android在4.4版本以後開始出現狀態列及導航欄透明化 實現程式碼如下 If (Build.Version.Sdk_Int >= Build.Version_Codes.Kitkat)

Android 沉浸式模式與常見狀態導航效果

官方稱沉浸式狀態列為沉浸式模式。什麼是沉浸式?沉浸式就是讓人專注當前的(由設計者營造)情境下感到愉悅和滿足,而忘記真實的情境。什麼是Android中的沉浸式?當啟用該模式,應用程式的介面將佔據整個螢幕,自動隱藏系統的狀態列和導航欄,讓應用程式內容可以在最大顯示範圍呈現,增加大屏體驗,而當需要檢視通知的時候只需

Android隱藏狀態導航

public class BaseActivity extends AppCompatActivity { @Override public void onWindowFocusChanged(boolean hasFocus) { super

android 自定義狀態導航分析與實現

效果   android 4.4之後,系統是支援自定義狀態列和導航欄的,舉個最典型的例子就是bilibili客戶端了(iOS版本和android版本能用兩套完全不一樣符合各自系統的設計ui,良心啊~),頂部狀態列為粉色,底部導航欄為半透明色:      接

Android開發 之 動態顯示和隱藏狀態導航

// //佈局填充狀態列,設定透明 // if (Build.VERSION.SDK_INT >= 21) { // View decorView = getWindow().getDecorView(); // int optio

Android 4.4之後狀態導航細節美化(沉浸式狀態

1. 簡介 其實標題我是打算叫“搶眼的沉浸式狀態列”,但是檢視多篇文章以及官方文件發現,雖然“沉浸式狀態列”這個名字已經爛大街並且只要一提到這個標籤大家都知道是一個什麼樣的效果,其實沉浸式並不是這樣理解的,檢視官方文件發現,Google定義的沉浸式

Android 通過 style 設定狀態導航等的顏色

我們在有些時候會有這個樣的需求,需要修改狀態列,導航欄。系統控制元件的顏色。我們可以先定義一個style,然後在這個style中設定我們需要顏色的屬性,最後在清單檔案中來給某個Activity設定主題即可。程式碼如下: <style name="

android4.4以上沉浸式狀態導航實現以及Bar的其他管理

自從android4.4開始,android手機狀態列再也不是一成黑的時代,之前叫做變色龍,miui6釋出會把他叫做沉浸式,之後大家就自然而然的接受了沉浸式這個名稱,其實實際應該叫做Translucent Bar,即為透明狀態列。   沉浸式實現原理其實是使整個activity佈局延伸到整個螢幕,然

修改狀態導航顏色

1.修改狀態列 可進行自定義 public class StatusBarView extends View { private Context context; public StatusBarView(Context context) { this(con

【實戰乾貨】透明狀態導航的終極解決方案

本文主要分享了透明狀態列和導航欄的終極解決方案。以後這類問題,一文搞定 這個技術痛點遇到過的都懂~本文幫你徹底解決這個痛點~還不快收藏   背景   在我做 Android 開發之前,我就發現有些 App 的狀態列和導航欄有透明效果,或者是沉浸式效果,比如說酷

狀態導航的設定

其中有些值是要相互配合使用,單一使用沒有效果,需要的時候查詢文件,都有解釋, 或是多嘗試幾次,也就知道該用哪個了。 // 沉浸式狀態列 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

iOS 更改狀態導航顏色的幾種方法

ios上狀態列 就是指的最上面的20畫素高的部分 狀態列分前後兩部分,要分清這兩個概念,後面會用到: 前景部分:就是指的顯示電池、時間等部分; 背景部分:就是顯示黑色或者圖片的背景部分; (一)設定statusBar的【前景部分】 簡單來說,就是設定顯示電池電量、時間、網路部分標示的顏色, 這裡只能設定兩種

Android狀態與標題風格一致

首先只有Android4.4也就是api19及以上才可以使用沉浸式狀態列。 第一步:在res目錄下新建一個values-v19資料夾 新建一個style.xml,新增程式碼 <resources  <style name="AppBaseTheme"

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

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