Reputation: 3163
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.
Upvotes: 228
Views: 205755
Reputation: 1026
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 }
Upvotes: 31
Reputation: 6918
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;
Upvotes: 413
Reputation: 1796
In the new world of Compose on one line
val (height, width) = LocalConfiguration.current.run { screenHeightDp.dp to screenWidthDp.dp }
Upvotes: 3
Reputation: 537
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;
}
Upvotes: 2
Reputation: 4073
Answer in kotlin:
context?.let {
val displayMetrics = it.resources.displayMetrics
val dpHeight = displayMetrics.heightPixels / displayMetrics.density
val dpWidth = displayMetrics.widthPixels / displayMetrics.density
}
Upvotes: 5
Reputation: 9
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.
Upvotes: 0
Reputation: 1868
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();
Upvotes: 2
Reputation: 3238
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;
Upvotes: 7
Reputation: 1389
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.
Upvotes: 128
Reputation: 116322
How about using this instead ?
final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;
Upvotes: 11
Reputation: 15
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);
Upvotes: -5
Reputation: 3160
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)
Upvotes: 8