以像素为单位获取屏幕尺寸

问题描述 投票:1768回答:39

我创建了一些自定义元素,我想以编程方式将它们放置在右上角(从顶部边缘开始的n像素和从右边缘开始的m像素)。因此我需要获得屏幕宽度和屏幕高度,然后设置位置:

int px = screenWidth - m;
int py = screenHeight - n;

如何在主要活动中获得screenWidthscreenHeight

android layout screen pixel dimensions
39个回答
3429
投票

如果您想要显示尺寸(以像素为单位),您可以使用getSize

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

如果你不在Activity,你可以通过Display获得默认的WINDOW_SERVICE

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

如果你在一个片段中想要完成这个,只需使用Activity.WindowManager(在Xamarin.Android中)或getActivity()。getWindowManager()(在java中)。

在引入getSize之前(在API级别13中),您可以使用现已弃用的getWidthgetHeight方法:

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

但是,对于您正在描述的用例,布局中的边距/填充似乎更合适。

另一种方式是:DisplayMetrics

描述有关显示的一般信息的结构,例如其大小,密度和字体缩放。要访问DisplayMetrics成员,请初始化如下对象:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

我们可以使用widthPixels获取以下信息:

“显示器的绝对宽度,以像素为单位。”

例:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);

17
投票

对于使用XML动态扩展,有一个名为“android:layout_weight”的属性

以下示例,根据synic对getWidth()的响应进行修改,显示一个按钮占据屏幕的75%(权重= .25),文本视图占据屏幕剩余的25%(权重= .75)。

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

17
投票

这是我用于任务的代码:

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}

看起来足够干净但是,请注意弃用。


17
投票

这不是一个更好的解决方案吗? this thread提供您需要的一切,并且可以使用API​​ 1。

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>

您还可以使用// `activity` is an instance of Activity class. Display display = activity.getWindowManager().getDefaultDisplay(); Point screen = new Point(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(screen); } else { screen.x = display.getWidth(); screen.y = display.getHeight(); } 获取实际显示(包括屏幕装饰,例如状态栏或软件导航栏),但这仅适用于17+。

我错过了什么吗?


15
投票

只是添加到Francesco的答案。另一个更贴切的观察者,如果你想找到窗口中的位置或屏幕中的位置是DisplayMetrics

这也可用于查找onCreate()时间内大部分未知的视图的其他属性,例如滚动位置,缩放位置。


15
投票

找到屏幕的宽度和高度:

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

使用此功能,我们可以获得最新及以上的SDK 13。

getRealMetrics

14
投票

在Activity中使用以下代码。

ViewTreeObserver.OnPreDrawListener()

14
投票
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

11
投票

我发现这就行了。

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}

11
投票

需要说明的是,如果你不在DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int height = metrics.heightPixels; int wwidth = metrics.widthPixels; ,但在DisplayMetrics dimension = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dimension); int w = dimension.widthPixels; int h = dimension.heightPixels; (或在你的范围内有Rect dim = new Rect(); getWindowVisibleDisplayFrame(dim); 类型的变量),则不需要使用Activity。然后你可以使用至少两种方式。

第一:

View

第二:

View

我们在这里调用的所有方法都不会被弃用。


11
投票
WINDOW_SERVICE

362
投票

一种方法是:

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

它已弃用,您应该尝试使用以下代码。前两行代码为您提供了DisplayMetrics对象。此对象包含heightPixelswidthPixels等字段。

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;

9
投票

要获取屏幕尺寸,请使用显示指标

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

获取高度和宽度(以像素为单位)

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

8
投票

这不是OP的答案,因为他想要实际像素的显示尺寸。我想要“设备无关 - 像素”中的尺寸,并在这里汇总答案public class AndroidScreenActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); String str_ScreenSize = "The Android Screen is: " + dm.widthPixels + " x " + dm.heightPixels; TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize); mScreenSize.setText(str_ScreenSize); } } DisplayMetrics displayMetrics = new DisplayMetrics(); if (context != null) WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display defaultDisplay = windowManager.getDefaultDisplay(); defaultDisplay.getRealMetrics(displayMetrics); } 我想出了这个:

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;

7
投票

使用DisplayMetrics(API 1)有一种不推荐的方法可以避免try / catch杂乱:

https://stackoverflow.com/a/17880012/253938

7
投票

我会像这样包装getSize代码:

https://stackoverflow.com/a/6656774/253938

7
投票

你可以使用以下方法获得身高:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);

和宽度大小使用

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;

5
投票

对于谁在没有状态栏和操作栏的情况下搜索可用的屏幕尺寸(也感谢Swapnil的回答):

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}

5
投票

首先加载XML文件,然后编写以下代码:

getResources().getDisplayMetrics().heightPixels;

根据屏幕分辨率显示宽度和高度。


5
投票

请遵循以下方法:

getResources().getDisplayMetrics().widthPixels; 

4
投票

在活动的onCreate中,有时您需要知道布局的可用空间的精确尺寸。经过一番思考后,我就这样做了。

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    screen_h -= getResources().getDimensionPixelSize(resId);
}

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}

如果由于某种原因您不想在Android清单中添加其他活动,则可以这样做:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

4
投票

如果您不需要WindowManagers,Points或Displays的开销,则可以获取XML中最顶层View项的height和width属性,前提是它的高度和宽度设置为match_parent。 (只要您的布局占用整个屏幕,这都是正确的。)

例如,如果您的XML以这样的内容开头:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}

然后public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); startActivityForResult(new Intent(this, Measure.class), 1); // Return without setting the layout, that will be done in onActivityResult. } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { // Probably can never happen, but just in case. if (resultCode == RESULT_CANCELED) { finish(); return; } int width = data.getIntExtra("Width", -1); // Width is now set to the precise available width, and a layout can now be created. ... } } public final class Measure extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a LinearLayout with a MeasureFrameLayout in it. // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way. LinearLayout linearLayout = new LinearLayout(this); LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this); measureFrameLayout.setLayoutParams(matchParent); linearLayout.addView(measureFrameLayout); this.addContentView(linearLayout, matchParent); // measureFrameLayout will now request this second activity to finish, sending back the width. } class MeasureFrameLayout extends FrameLayout { boolean finished = false; public MeasureFrameLayout(Context context) { super(context); } @SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (finished) { return; } finished = true; // Send the width back as the result. Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec)); Measure.this.setResult(Activity.RESULT_OK, data); // Tell this activity to finish, so the result is passed back. Measure.this.finish(); } } } 将返回屏幕的宽度,public class MainActivity extends Activity { static Activity measuringActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle extras = getIntent().getExtras(); if (extras == null) { extras = new Bundle(); } int width = extras.getInt("Width", -2); if (width == -2) { // First time in, just start another copy of this activity. extras.putInt("Width", -1); startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1); // Return without setting the layout, that will be done in onActivityResult. return; } if (width == -1) { // Second time in, here is where the measurement takes place. // Create a LinearLayout with a MeasureFrameLayout in it. // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way. LinearLayout linearLayout = new LinearLayout(measuringActivity = this); LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this); measureFrameLayout.setLayoutParams(matchParent); linearLayout.addView(measureFrameLayout); this.addContentView(linearLayout, matchParent); // measureFrameLayout will now request this second activity to finish, sending back the width. } } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { // Probably can never happen, but just in case. if (resultCode == RESULT_CANCELED) { finish(); return; } int width = data.getIntExtra("Width", -3); // Width is now set to the precise available width, and a layout can now be created. ... } class MeasureFrameLayout extends FrameLayout { boolean finished = false; public MeasureFrameLayout(Context context) { super(context); } @SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (finished) { return; } finished = true; // Send the width back as the result. Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec)); MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data); // Tell the (second) activity to finish. MainActivity.measuringActivity.finish(); } } 将返回屏幕的高度。


115
投票

它可能无法回答你的问题,但知道(当我提出这个问题时我自己正在寻找它)可能是有用的,如果你需要一个View的维度,但你的代码在布局尚未布局时正在执行(例如在onCreate()中)你可以用ViewTreeObserver.OnGlobalLayoutListener设置一个View.getViewTreeObserver().addOnGlobalLayoutListener()并在那里放置需要视图维度的相关代码。布局布局后将调用侦听器的回调。


3
投票

我有一个启动画面活动,其中LinearLayout作为根视图,其宽度和高度都有match_parent。这是该活动的<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/entireLayout" android:layout_width="match_parent" android:layout_height="match_parent" > 方法中的代码。我在应用程序的所有其他活动中使用这些度量。

findViewById(R.id.entireLayout).getWidth()

以下是您在上面看到的方法的实现:

findViewById(R.id.entireLayout).getHeight()

这导致可用显示器的高度和宽度,不包括任何类型的条(状态栏,导航栏),适用于所有API版本和不同类型的设备(手机和平板电脑)。


105
投票

(2012年回答,可能已过时)如果你想支持precomb,你需要在API 13之前提供向后兼容性。例如:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

当然,已弃用的方法最终会从最新的SDK中取出,但我们仍然依赖大多数拥有Android 2.1,2.2和2.3的用户,这就是我们留下的。


66
投票

我尝试了所有可能的“解决方案”并没有成功,我注意到Elliott Hughes的“Dalvik Explorer”应用程序总是在任何Android设备/操作系统版本上显示正确的尺寸。我最后看了他的开源项目,可以在这里找到:https://code.google.com/p/enh/

这是所有相关代码:

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

编辑:稍微改进版本(避免在不支持的操作系统版本上触发异常):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

47
投票

最简单的方法:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

46
投票

要访问Android设备状态栏的高度,我们更喜欢以编程方式获取它:

Sample code

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

变量result给出像素中的高度。

For quick access

有关qazxsw poi,qazxsw poi和qazxsw poi身高的更多信息,请查看Title bar


30
投票

首先获取视图(例如,通过Navigation bar),然后您可以在视图本身上使用Content View


26
投票

我有两个函数,一个用于发送上下文,另一个用于获取高度和宽度(以像素为单位):

Android Device Screen Sizes

findViewById()
© www.soinside.com 2019 - 2024. All rights reserved.