簡體   English   中英

在Android中獲取屏幕高度

[英]Get the screen height in Android

如何在Android中獲得可用的屏幕高度? 我需要高度減去狀態欄/菜單欄或可能在屏幕上的任何其他裝飾,我需要它適用於所有設備。 另外,我需要在onCreate函數中知道這一點。 我知道之前已經問過這個問題,但我已經嘗試過他們的解決方案而且沒有一個能夠工作。 以下是我嘗試過的一些事情:

我已經在API 7-17上測試了這個代碼。不幸的是,在API 13上,水平和垂直底部都有額外的空間,而在API 10,8和7上,水平和垂直底部沒有足夠的空間。 (我沒有測試過時的API):

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;

TypedValue tv = new TypedValue();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        screenHeight -= TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
    screenHeight -= getResources().getDimensionPixelSize(resourceId);

這不考慮狀態欄/菜單欄:

Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();

這也不是:

Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
screenHeight = size.y;

這不是:

Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
screenWidth = size.x;
screenHeight = size.y;

這不起作用:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
// since SDK_INT = 1;
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
try
{
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    screenWidth = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
    screenHeight = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
}
catch (Exception ignored)
{
    // Do nothing
}
try
{
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(display, realSize);
    screenWidth = realSize.x;
    screenHeight = realSize.y;
}
catch (Exception ignored)
{
    // Do nothing
}

然后我使用以下代碼從屏幕高度中減去狀態欄和菜單欄的高度:

int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)
    result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;
result = 0;
if (screenHeight >= screenWidth)
    resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
else
    resourceId = getResources().getIdentifier("navigation_bar_height_landscape", "dimen", "android");
if (resourceId > 0)
    result = getResources().getDimensionPixelSize(resourceId);
screenHeight -= result;

在API 17上,它正確地以縱向方式計算狀態欄和菜單欄的高度,但不以橫向方式計算。 在API 10上,它返回0.我需要它在所有設備或最小API 7上理想地工作。

如果您想要顯示尺寸(以像素為單位),可以使用getSize

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

如果您不在Activity ,則可以通過WINDOW_SERVICE獲取默認顯示:

WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
display.getSize(size);
int width = size.x;
int height = size.y;

在引入getSize之前(在API級別13中),您可以使用現已棄用getWidth和getHeight方法:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

參考: 獲取屏幕尺寸,以像素為單位

工作方案:

創建兩個虛擬視圖:

 <View
    android:id="@+id/top"
    android:layout_height="0dp"
    android:layout_width="match_parent"
    android:layout_alignParentTop="true" />

<View
        android:id="@+id/bottom"
        android:layout_height="0dp"
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true" />

現在,您應該在這兩個視圖上調用getLocationOnScreen(int [])來接收它們的位置。 此函數返回2個整數的數組。 第一個是x,第二個是y。 我們只需要y。 另請注意,僅在創建所有視圖並退出onCreate方法后才返回正確的值。

我在一個從viewpager調用的常規片段上測試了這段代碼。

代碼在我的片段的onCreateView方法中。 我仍然必須使用postDelayed來獲取正確的值。

final View top = (View) view.findViewById(R.id.top);
    final View bottom = (View) view.findViewById(R.id.bottom);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {

            int topLoc[] = new int[2];
            top.getLocationOnScreen(topLoc);
            int BottomLoc[] = new int[2];
            bottom.getLocationOnScreen(BottomLoc);
            Log.d(Constants.debug, "topY: "+ topLoc[1]+" BottomY:" + BottomLoc[1]);
        }
    },4000);

我有一個Nexus 4。

在常規模式下(狀態欄和顯示的軟按鈕):

07-05 02:28:23.367      565-565/com.torcellite.xx D/xx: topY: 50 BottomY:1182

在全屏模式下(未顯示狀態欄或軟按鈕):

07-05 02:29:17.360      707-707/com.torcellite.xx D/xx: topY: 0 BottomY:1280

你現在所要​​做的就是減去。

用於顯示

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;

對於狀態欄

public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

我沒有嘗試過不同的API,但我正在使用這些值來判斷屏幕鍵盤是否已啟動。 也許你可以試試這個和寬度相當的東西來得到你需要的東西?

Rect r = new Rect();
view.getWindowVisibleDisplayFrame(r);
int
    screenHeight = view.getRootView().getHeight(), // height of the entire screen
    appHeight = r.bottom - r.top, // height of the entire app
    statusBarHeight = r.top, // height of the statusbar
    pageHeight = view.getHeight(), // height of the app without title
    appTitleHeight = appHeight - pageHeight, // height of the only the app title
    topHeight = statusBarHeight + appTitleHeight;
final View view = findViewById(R.id.root);
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // calculate the height in here...

        ViewTreeObserver vto = view.getViewTreeObserver();
        vto.removeGlobalOnLayoutListener(this);
    }
});

onCreate使用此偵聽器(自api 1起可用)。 您需要將id @+id/root分配給xml布局中的父級。 大小無法返回0的結果,因為只要布局已在視圖中定位,此偵聽器就會進行回調。

Display currentDisplay = getWindowManager().getDefaultDisplay();
        float dw = currentDisplay.getWidth();
        float dh = currentDisplay.getHeight();

dh會給你屏幕高度。

如何將子類View設置為Activity的根目錄。 使此視圖填滿屏幕(它不會超過狀態欄)並覆蓋onSizeChanged() 存儲這些值並為它們編寫一個getter。

它可能無法回答你的問題,但知道(當我提出這個問題時我自己正在尋找它)可能是有用的,如果你需要一個View的維度,但你的代碼在布局尚未布局時正在執行(例如在onCreate()中)您可以使用View.getViewTreeObserver()。addOnGlobalLayoutListener()設置ViewTreeObserver.OnGlobalLayoutListener,並在其中放置需要視圖維度的相關代碼。 布局布局后將調用偵聽器的回調。

禮貌-Francesco Feltrinelli

你可以嘗試這樣做。

獲取活動加載的根布局的高度。 如果它沒有填滿屏幕,則將其放在另一個布局中,其高度屬性為fill_parent。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM