How to determine the screen width in terms of dp or dip at runtime in Android?
Asked Answered
E

13

226

I need to code the layout of the android widgets using dip/dp (in java files). At runtime if I code,

int pixel=this.getWindowManager().getDefaultDisplay().getWidth();

this return the screen width in pixels (px). To convert this to dp, I coded:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

This does not seem to be returning correct answer. I made the emulator of WVGA800 whose screen resolution is 480 by 800. When the run the emulator and let the code print the values of pixel and dp, it came to 320 in both. This emulator is 240 dpi whose scale factor would be 0.75.

Ethical answered 24/6, 2011 at 9:6 Comment(0)
S
412

As @Tomáš Hubálek mentioned;
Try something like:

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

OR

Try old answer:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
         
float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;
Springbok answered 1/8, 2012 at 8:19 Comment(4)
Why it is necessary to call WindowManager? What about this code? DisplayMetrics displayMetrics = resources.getDisplayMetrics(); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;Wapentake
This didn't work for me using a very high density screen. It was as if it only got a small portion of the screen. This solution worked for me: https://mcmap.net/q/120180/-how-to-get-android-screen-size-programmatically-once-and-for-all Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y;Fults
@dsdsdsdsd : context is any instance of the Context class. Most notably, Activity is a sub class of Context (so use this in an Activity, and getActivity() in a Fragment). Application and Service are also sub classes of Context.Spearing
Using Resources.getSystem() does not work well on foldables and other multi-screen devices. Also see developer.android.com/guide/practices/…Mahan
F
128

I stumbled upon this question from Google, and later on I found an easy solution valid for API >= 13.

For future references:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

See Configuration class reference

Edit: As noted by Nick Baicoianu, this returns the usable width/height of the screen (which should be the interesting ones in most uses). If you need the actual display dimensions stick to the top answer.

Fula answered 27/5, 2014 at 23:43 Comment(3)
One important difference between using Configuration's screenWidthDp/screenHeightDp vs DisplayMetrics widthPixels/heightPixels is Configuration returns the usable display dimensions (minus the status bar etc), while DisplayMetrics returns the full screen dimensions.Ephrem
This is only for API Level 13 and upOnstage
To add to @NickBaicoianu's comment, both the getConfiguration() and getDisplayMetrics() methods work in multi-window mode. i.e. the sizes reflect that of the window, not the screen.Daze
D
31

2023 Answer simplified for Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }

As one-liner:

val (height, width) = resources.displayMetrics.run { heightPixels/density to widthPixels/density }

For Jetpack Compose:

val (height, width) = LocalConfiguration.current.run { screenHeightDp.dp to screenWidthDp.dp }
Domitian answered 4/2, 2020 at 21:45 Comment(2)
But where is the density. I guess there needs some more lines.Maihem
The density comes from DisplayMetrics within the run block.Scheers
L
11

How about using this instead ?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;
Laws answered 27/1, 2014 at 21:14 Comment(0)
L
8

You are missing default density value of 160.

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

In other words, if you design you layout with width equal to 160dip in portrait mode, it will be half of the screen on all ldpi/mdpi/hdpi devices(except tablets, I think)

Lynnell answered 24/6, 2011 at 9:18 Comment(2)
What you have answered is the logical reasoning behind my question. I understand this. How should I code this in java so that at runtime whatever the screen resolution is,correct dpi width is picked by the code?Ethical
Hope I get it right this time :) Use DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics); within Activity. Then, outMetrics.density will give you the scale factor of the current device, as stated in the docsLynnell
K
7
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;
Keening answered 22/7, 2017 at 18:27 Comment(2)
Consider giving some explanationRespectability
Using Resources.getSystem() does not work well on foldables and other multi-screen devicesMahan
L
5

Answer in kotlin:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }
Loam answered 1/8, 2019 at 13:48 Comment(0)
O
3

In the new world of Compose on one line

val (height, width) = LocalConfiguration.current.run { screenHeightDp.dp to screenWidthDp.dp }
Oppress answered 17/11, 2021 at 16:29 Comment(0)
A
2

Get Screen Width and Height in terms of DP with some good decoration:

Step 1: Create interface

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

Step 2: Create implementer class

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

Step 3: Get width and height in activity:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();
Angelicangelica answered 10/1, 2019 at 11:5 Comment(4)
Does this return height and width in pixel or dp?Willywillynilly
as called .density that's why its give you in dpAngelicangelica
I don't think it's a good idea to add tones of code to your app to solve a simple taskEuthenics
Sir it's upto you whether to implement class or directly code it. From the defined class you can easily extract the code for direct implementation.Angelicangelica
Q
2

This is a copy/pastable function to be used based on the previous responses.

  /**
     * @param context
     * @return the Screen height in DP
     */
    public static float getHeightDp(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
        return dpHeight;
    }

    /**
     * @param context
     * @return the screnn width in dp
     */
    public static float getWidthDp(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
        return dpWidth;
    }
Quinquereme answered 21/1, 2021 at 8:18 Comment(0)
C
0

If you just want to know about your screen width, you can just search for "smallest screen width" in your developer options. You can even edit it.

Clubman answered 30/4, 2019 at 6:16 Comment(0)
D
0

val screenSize = size.toDpSize()

Displant answered 23/1 at 16:25 Comment(0)
P
-5

Your problem is with casting the float to an int, losing precision. You should also multiply with the factor and not divide.

Do this:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);
Pygmy answered 13/10, 2011 at 10:36 Comment(1)
This answer is incorrect. From developer.android.com/guide/practices/…, Pixel = Dp * Density.Gothurd

© 2022 - 2024 — McMap. All rights reserved.