首页 文章

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

提问于
浏览
1713

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

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

如何在主Activity中获得 screenWidthscreenHeight

30 回答

  • 3370

    它可能无法回答你的问题,但知道(当我遇到这个问题时我自己正在寻找它)可能是有用的,如果你需要一个View的维度,但你的代码在布局尚未布局时正在执行(例如在 onCreate() 中)您可以使用 View.getViewTreeObserver().addOnGlobalLayoutListener() 设置 ViewTreeObserver.OnGlobalLayoutListener 并在布局布局时调用需要视图的相关代码's dimension there. The listener' s回调 .

  • 15

    最简单的方法:

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

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

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

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

  • 17

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

    以下示例,根据synic在this thread上的响应进行修改,显示占据屏幕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>
    
  • 8

    我发现这样做了 .

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

    如果您想要显示尺寸(以像素为单位),可以使用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 获取以下信息:

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

    Example:

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

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

    示例代码

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

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

    快速访问

    Enter image description here

    有关 Title barNavigation barContent View 的高度的更多信息,请查看Android Device Screen Sizes .

  • 11

    我会像这样包装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;
    }
    
  • 63

    一种方法是:

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

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

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    
    int height = metrics.heightPixels;
    int width = metrics.widthPixels;
    
  • 4
    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);
        }
    }
    
  • 9

    请遵循以下方法:

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

    我已经尝试了所有可能的"solutions"失败了,我注意到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) {
    }
    
  • 44

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

  • 29

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

    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;
    }
    
  • 113
    DisplayMetrics dimension = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dimension);
    int w = dimension.widthPixels;
    int h = dimension.heightPixels;
    
  • 43

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

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

  • 6

    需要说明的是,如果您不在 Activity 中,但在 View 中(或在您的范围内具有 View 类型的变量),则无需使用 WINDOW_SERVICE . 然后你可以使用至少两种方式 .

    第一:

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

    第二:

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

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

  • 17

    在活动的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();
            }
        }
    }
    

    如果由于某种原因您不想在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();
        }
    }
    
  • 3

    使用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;
    
  • 25

    这不是一个更好的解决方案吗? 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 .

    我错过了什么吗?

  • 15

    要获取屏幕尺寸,请使用显示矩阵

    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;
    
  • 14

    您可以使用以下方法获取 height 尺寸:

    getResources().getDisplayMetrics().heightPixels;
    

    width 大小使用

    getResources().getDisplayMetrics().widthPixels;
    
  • 11

    这不是OP的答案,因为他想要实际像素的显示尺寸 . 我想要"device-independent-pixels"中的维度,并将这里的答案放在一起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);
    
  • 5

    (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的用户,这就是我们留下的 .

  • 5

    这是我用于任务的代码:

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

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

  • 11

    在Activity中使用以下代码 .

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

    如果您不需要WindowManagers,Points或Displays的开销,则可以获取XML中最顶层View项的height和width属性,前提是它的高度和宽度设置为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() 将返回屏幕的高度 .

  • 103

    我有一个启动画面活动,其中LinearLayout作为根视图,其宽度和高度具有match_parent . 这是该活动的 onCreate() 方法中的代码 . 我在应用程序的所有其他活动中使用这些度量 .

    int displayWidth = getRawDisplayWidthPreHoneycomb();
    int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
    int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
    pf.setScreenParameters(displayWidth, usableDisplayHeight);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
        myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                if (left == 0 && top == 0 && right == 0 && bottom == 0) {
                    return;
                }
                int displayWidth = Math.min(right, bottom);
                int usableDisplayHeight = Math.max(right, bottom);
                pf.setScreenParameters(displayWidth, usableDisplayHeight);
            }
        });
    }
    

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

    private int getRawDisplayWidthPreHoneycomb() {
        WindowManager windowManager = getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getMetrics(displayMetrics);
    
        int widthPixels = displayMetrics.widthPixels;
        int heightPixels = displayMetrics.heightPixels;
    
        return Math.min(widthPixels, heightPixels);
    }
    
    private int getRawDisplayHeightPreHoneycomb() {
        WindowManager w = getWindowManager();
        Display d = w.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        d.getMetrics(metrics);
    
        int widthPixels = metrics.widthPixels;
        int heightPixels = metrics.heightPixels;
    
        return Math.max(widthPixels, heightPixels);
    }
    
    public int getStatusBarHeight() {
        int statusBarHeight = 0;
    
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
    
        return statusBarHeight;
    }
    

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

  • 4

    对于谁在没有 Status BarAction Bar 的情况下搜索可用的屏幕尺寸(也感谢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);
    }
    
  • 7

    找到屏幕的宽度和高度:

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

相关问题