如何在 Android 中获取屏幕尺寸(像素)

发布于 2024-07-25 19:00:26 字数 289 浏览 5 评论 0原文

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

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

How do I get screenWidth and screenHeight in the main Activity?

I created some custom elements, and I want to programmatically place them to the upper right corner (n pixels from the top edge and m pixels from the right edge). Therefore I need to get the screen width and screen height and then set position:

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

How do I get screenWidth and screenHeight in the main Activity?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

披肩女神 2024-08-01 19:00:27

最简单的方法:

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

Simplest way:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 
最后的乘客 2024-08-01 19:00:27

为了访问 Android 设备状态栏的高度,我们更喜欢通过编程方式来获取它:

示例代码

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

变量 result 给出以像素为单位的高度。

如需快速访问

在此处输入图像描述

有关标题栏高度的更多信息,导航栏内容视图,请在Android设备上查看屏幕尺寸

For accessing the height of the status bar for Android devices, we prefer a programmatic way to get it:

Sample code

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

The variable result gives the height in the pixel.

For quick access

Enter image description here

For more information about height of Title bar, Navigation bar and Content View, kindly look on Android Device Screen Sizes.

淤浪 2024-08-01 19:00:27

首先获取视图(例如通过 findViewById()),然后您可以使用 getWidth() 在视图本身上。

First get view (eg. by findViewById()) and then you can use getWidth() on the view itself.

罗罗贝儿 2024-08-01 19:00:27

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

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;
}

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;
}

I have two functions, one for sending the context and the other getting height and width in pixels:

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;
}

and

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;
}
遇见了你 2024-08-01 19:00:27

对于使用 XML 进行动态缩放,有一个名为“android:layout_weight”的属性

下面的示例根据 synic 在 此线程,显示一个占据屏幕 75% 的按钮(权重 = .25)和一个占据屏幕剩余 25% 的文本视图(权重 = .75) )。

<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>

For dynamically scaling using XML there is an attribute called "android:layout_weight"

The below example, modified from synic's response on this thread, shows a button that takes up 75% of the screen (weight = .25) and a text view taking up the remaining 25% of the screen (weight = .75).

<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>
涫野音 2024-08-01 19:00:27

这是我用于该任务的代码:

// `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();
}

看起来足够干净,但仍处理弃用问题。

This is the code I use for the task:

// `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();
}

Seems clean enough and yet, takes care of the deprecation.

梦在深巷 2024-08-01 19:00:27

这不是一个更好的解决方案吗? DisplayMetrics 附带您需要的一切,并可从 API 1 开始工作。

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

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

您还可以使用 getRealMetrics,但这仅适用于 17+。

我错过了什么吗?

Isn't this a much better solution? DisplayMetrics comes with everything you need and works from API 1.

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

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

You can also get the actual display (including screen decors, such as Status Bar or software navigation bar) using getRealMetrics, but this works on 17+ only.

Am I missing something?

杀手六號 2024-08-01 19:00:27

只是添加到弗朗西斯科的答案中。 如果您想找出窗口中的位置或屏幕中的位置,另一个更合适的观察者是
ViewTreeObserver.OnPreDrawListener()

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

Just adding to Francesco's answer. The other observer that is more apt, if you want to find out the location in window or location in screen is
ViewTreeObserver.OnPreDrawListener()

This also can be used to find other attributes of a view that is mostly unknown at onCreate() time e.g. the scrolled position, the scaled position.

只是偏爱你 2024-08-01 19:00:27

查找屏幕的宽度和高度:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

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

// 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);
}

Find width and height of the screen:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Using this, we can get the latest and above SDK 13.

// 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);
}
冷血 2024-08-01 19:00:27
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
百变从容 2024-08-01 19:00:27

在 Activity 中使用以下代码。

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;

Using the following code in Activity.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
野味少女 2024-08-01 19:00:27

需要说的是,如果您不在 Activity 中,而是在 View 中(或者在您的作用域中有 View 类型的变量),则有不需要使用WINDOW_SERVICE。 那么你至少可以使用两种方式。

第一:

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

第二:

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

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

Need to say, that if you are not in Activity, but in View (or have variable of View type in your scope), there is not need to use WINDOW_SERVICE. Then you can use at least two ways.

First:

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

Second:

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

All this methods we call here is not deprecated.

梦中的蝴蝶 2024-08-01 19:00:27

这不是OP的答案,因为他想要以实际像素为单位的显示尺寸。 我想要“设备独立像素”中的尺寸,并从这里汇总答案 https://stackoverflow.com/a/17880012 /253938 和这里 https://stackoverflow.com/a/6656774/253938 我想出了这个:

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

This is not an answer for the OP, as he wanted the display dimensions in real pixels. I wanted the dimensions in "device-independent-pixels", and putting together answers from here https://stackoverflow.com/a/17880012/253938 and here https://stackoverflow.com/a/6656774/253938 I came up with this:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
兰花执着 2024-08-01 19:00:27
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);
    }
}
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);
    }
}
乞讨 2024-08-01 19:00:27

要获取屏幕尺寸,请使用显示度量

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;

For getting the screen dimensions use display metrices

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

Get the height and width in pixels

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
亢潮 2024-08-01 19:00:27

我发现这成功了。

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);

I found this did the trick.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
べ繥欢鉨o。 2024-08-01 19:00:27

您可以使用 : 获取高度尺寸,使用以下

getResources().getDisplayMetrics().heightPixels;

方式获取宽度尺寸

getResources().getDisplayMetrics().widthPixels; 

You can do get the height size using :

getResources().getDisplayMetrics().heightPixels;

and the width size using

getResources().getDisplayMetrics().widthPixels; 
九局 2024-08-01 19:00:27

有一种未弃用的方法可以使用 DisplayMetrics (API 1) 来执行此操作,从而避免 try/catch 混乱:

 // 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;

There is a non-deprecated way to do this using DisplayMetrics (API 1), that avoids the try/catch messiness:

 // 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;
只为一人 2024-08-01 19:00:27

我将像这样包装 getSize 代码:

@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;
}

I would wrap the getSize code like this:

@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;
}
缺⑴份安定 2024-08-01 19:00:27

对于正在寻找没有状态栏操作栏可用屏幕尺寸的人(也感谢 Swapnil 的回答):

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);
}

For who is searching for usable screen dimension without Status Bar and Action Bar (also thanks to Swapnil's answer):

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);
}
关于从前 2024-08-01 19:00:27

科特林

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}
杀手六號 2024-08-01 19:00:27

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

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

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

First load the XML file and then write this code:

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

Show width and height according your screen resolution.

不爱素颜 2024-08-01 19:00:27

请按照以下方法操作:

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;
}

Follow the methods below:

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;
}
〃温暖了心ぐ 2024-08-01 19:00:27

在 Kotlin 中要简单得多。

val displayMetrics = Resources.getSystem().displayMetrics
displayMetrics.heightPixels
displayMetrics.widthPixels

Much simpler in Kotlin.

val displayMetrics = Resources.getSystem().displayMetrics
displayMetrics.heightPixels
displayMetrics.widthPixels
残月升风 2024-08-01 19:00:27

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

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();
        }
    }
}

如果由于某种原因您不想将另一个 Activity 添加到 Android 清单中,您可以这样做:

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();
    }
}    

There are times when you need to know the precise dimensions of the available space for a layout when in an activity's onCreate.
After some thought I worked out this way of doing it.

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();
        }
    }
}

If for some reason you don't want to add another activity to the Android manifest, you can do it this way:

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();
    }
}    
小糖芽 2024-08-01 19:00:27

如果您不想要 WindowManagers、Points 或 Displays 的开销,则可以获取 XML 中最顶层视图项的高度和宽度属性,前提是其高度和宽度设置为 match_parent。 (只要您的布局占据整个屏幕,情况就是如此。)

例如,如果您的 XML 以类似以下内容开头:

<?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() 将返回屏幕的高度。

If you don't want the overhead of WindowManagers, Points, or Displays, you can grab the height and width attributes of the topmost View item in your XML, provided its height and width are set to match_parent. (This is true so long as your layout takes up the entire screen.)

For example, if your XML starts with something like this:

<?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" >

Then findViewById(R.id.entireLayout).getWidth() will return the screen's width and findViewById(R.id.entireLayout).getHeight() will return the screen's height.

沫离伤花 2024-08-01 19:00:26

对于 API 级别 30WindowMetrics将使用.getBounds。 其用法示例可以在链接文档中找到:

 final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

旧答案:

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

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

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

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);

For API Level 30, WindowMetrics.getBounds is to be used. An example of its usage can be found in the linked docs:

 final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

Old answer:

If you want the display dimensions in pixels you can use getSize:

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

If you're not in an Activity you can get the default Display via WINDOW_SERVICE:

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

If you are in a fragment and want to acomplish this just use Activity.WindowManager (in Xamarin.Android) or getActivity().getWindowManager() (in java).

Before getSize was introduced (in API level 13), you could use the getWidth and getHeight methods that are now deprecated:

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

For the use case, you're describing, however, a margin/padding in the layout seems more appropriate.

Another way is: DisplayMetrics

A structure describing general information about a display, such as its size, density, and font scaling. To access the DisplayMetrics members, initialize an object like this:

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

We can use widthPixels to get information for:

"The absolute width of the display in pixels."

Example:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
月野兔 2024-08-01 19:00:26

它可能无法回答您的问题,但如果您需要视图的尺寸,但您的代码在其布局尚未布局时正在执行,那么了解(当我遇到这个问题时我自己正在寻找它)可能会很有用(例如在 onCreate() 中)您可以使用 View.getViewTreeObserver().addOnGlobalLayoutListener() 设置一个 ViewTreeObserver.OnGlobalLayoutListener 并放置相关的那里需要视图尺寸的代码。 布局完成后,将调用侦听器的回调。

It may not answer your question, but it could be useful to know (I was looking for it myself when I came to this question) that if you need a View's dimension but your code is being executed when its layout has not been laid out yet (for example in onCreate() ) you can setup a ViewTreeObserver.OnGlobalLayoutListener with View.getViewTreeObserver().addOnGlobalLayoutListener() and put the relevant code that needs the view's dimension there. The listener's callback will be called when the layout will have been laid out.

铁憨憨 2024-08-01 19:00:26

(2012年的答案,可能已经过时)如果你想支持Honeycomb之前的版本,你需要在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 的用户,但这就是我们所剩下的。

(2012 answer, may be out of date) If you want to support pre Honeycomb, you will need to put in backward compatibility prior to API 13. Something like:

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();
}

Of course the deprecated methods will eventually be taken out of the the most recent SDKs, but while we still rely on most of our users having Android 2.1, 2.2 and 2.3, this is what we are left with.

旧故 2024-08-01 19:00:26

我已经尝试了所有可能的“解决方案”,但均未成功,并且我注意到 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) {
}

I have tried all possible "solutions" unsuccessfully and I noticed that Elliott Hughes' "Dalvik Explorer" app always shows correct dimension on any Android device/OS version. I ended up looking at his open source project that can be found here: https://code.google.com/p/enh/

Here's all the relevant code:

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) {
}

EDIT: slightly improved version (avoid firing exceptions on non-supported OS version):

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) {
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文