950

I have created my application with the height and width given in pixels for a Pantech device whose resolution is 480x800.

I need to convert height and width for a G1 device.
I thought converting it into dp will solve the problem and provide the same solution for both devices.

Is there any easy way to convert pixels to dp?
Any suggestions?

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
Indhu
  • 9,806
  • 3
  • 18
  • 17
  • 1
    If you're looking to do a one-off conversion (for instance for exporting sprites from Photoshop), [here's a nifty converter](http://pixplicity.com/dp-px-converter/). – Paul Lammertsma Apr 22 '14 at 22:25
  • 3
    [`px`, `dp`, `sp` conversion formulas](https://stackoverflow.com/a/42108115/3681880) – Suragch Jul 29 '17 at 03:26
  • http://web.archive.org/web/20140808234241/http://developer.android.com/guide/practices/screens_support.html#dips-pels – caw Jun 28 '19 at 00:45

35 Answers35

1160

Java code:

// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dip,
    r.getDisplayMetrics()
);

Kotlin code:

 val dip = 14f
 val r: Resources = resources
 val px = TypedValue.applyDimension(
     TypedValue.COMPLEX_UNIT_DIP,
     dip,
     r.displayMetrics
 )

Kotlin extension:

val Number.toPx get() = TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP,
  this.toFloat(),
  Resources.getSystem().displayMetrics)
Hani
  • 140
  • 1
  • 6
prasobh
  • 12,105
  • 1
  • 14
  • 3
  • 406
    Note: The above is converting DIPs to Pixels. The original question asked how to convert pixels to Dips! – Eurig Jones Mar 13 '12 at 16:34
  • 13
    Here's a real answer to the OP: http://stackoverflow.com/questions/6656540/android-convert-px-to-dp-video-aspect-ratio – qix Apr 07 '12 at 01:34
  • 138
    Its funny how the answer is more helpful when it doesn't really answer the question -_- I thought I wanted what the question asked then I realized I didn't! So great answer. I do have a question. How can I obtain the last paramter for `applyDimension`? Can I just do `getResource().getDisplayMetrics()`, or is there something else? – Andy Aug 04 '12 at 03:30
  • 14
    NOTE: relatively expensive operation. Try to cache the values for quicker acces – Entreco Dec 04 '14 at 12:15
  • This is not the right way to make conversion from px to dp. Check @Mike Keskinov's answer. – box Dec 17 '15 at 09:34
  • 1
    I haven't tried it, but it's logically possible to convert from pixels to DP by using this code by doing the following: `float pixelsPerDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, r.getDisplayMetrics()); return dp / pixelsPerDp;` – DemonGyro Jan 05 '16 at 16:30
  • Please don't use this if you want to load a dp value from your dimens.xml, because the getResource().getDimension() already does that for you. If you want to directly round the base value and cast it to an int then use the getDimensionPixelSize() instead of getDimension(). – Aksiom Oct 31 '16 at 23:04
  • 11
    If have no access to `Context` object use `Resources.getSystem().getDisplayMetrics()` – Farshad Jun 23 '17 at 03:15
  • As @Andy said, most of searched how to convert pixel to dp, but the one we need often is to convert dp to pixel – Aman Sep 09 '21 at 00:43
940
/**
 * This method converts dp unit to equivalent pixels, depending on device density. 
 * 
 * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
 * @param context Context to get resources and device specific display metrics
 * @return A float value to represent px equivalent to dp depending on device density
 */
public static float convertDpToPixel(float dp, Context context){
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

/**
 * This method converts device specific pixels to density independent pixels.
 * 
 * @param px A value in px (pixels) unit. Which we need to convert into db
 * @param context Context to get resources and device specific display metrics
 * @return A float value to represent dp equivalent to px value
 */
public static float convertPixelsToDp(float px, Context context){
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Salam El-Banna
  • 3,784
  • 1
  • 22
  • 34
Muhammad Nabeel Arif
  • 19,140
  • 8
  • 51
  • 70
  • 12
    Might be worth returning an int Math.round(px) as most methods expect an integer value – SingleWave Games Jul 07 '15 at 10:23
  • 3
    @MuhammadBabar This is because 160 dpi (mdpi) is the baseline desity from which other densities are calculated. hdpi for instance is considered to be 1.5x the density of mdpi which is really just another way of saying 240 dpi. See Zsolt Safrany's answer below for all densities. – Stephen Aug 02 '15 at 02:52
  • 20
    @TomTasche: From the docs for [`Resource.getSystem()`](http://developer.android.com/reference/android/content/res/Resources.html#getSystem%28%29) (emphasis mine): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (**can not use dimension units**, does not change based on orientation, etc)." – Vicky Chijwani Aug 17 '15 at 20:39
  • pixel returns float? I don't think there is "a half of a pixel"... :) – Martin Pfeffer Oct 24 '15 at 20:56
  • 2
    Developer have a choice to ceil/floor the value. It is better to give control to developer. – Muhammad Nabeel Arif Oct 24 '15 at 23:04
  • 7
    I would recommand `DisplayMetrics.DENSITY_DEFAULT` instead of `160f` http://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEFAULT – milcaepsilon Jan 18 '16 at 13:56
  • 1
    This won't give the correct result. `(metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)` will return an `int`. It needs to be cast to double or float. – Gokhan Arik Mar 02 '16 at 20:11
  • 1
    @VickyChijwani `Resources.getSystem().getDisplayMetrics().densityDpi` still seems to work. – Livven Apr 05 '16 at 10:22
  • 1
    Instead of `(float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT` you could also just use `metrics.density`. – Livven Apr 05 '16 at 10:24
  • @Livven I know it works, but that's beside the point, which was that the implementation can change / stop working at any time because the _documentation_ doesn't match what we expect. – Vicky Chijwani May 10 '16 at 16:57
  • 1
    @VickyChijwani Fair enough. I often find that when the documentation doesn't match the behavior it's because the documentation is outdated or simply not properly maintained, rather than the actual behavior being unintended. With some, maybe even most frameworks, relying only on the documentation would pretty much prevent you from getting any work done or even cause bugs. – Livven May 11 '16 at 09:55
  • what is that??? I convert 3dp to px using it and I get 1564.5px??. it's better to use https://developer.android.com/guide/practices/screens_support.html#screen-independence – user25 Aug 28 '16 at 13:41
  • 1
    HAHAHAAHAA. Pixels as a FLOAT , that's good... I am wondering, How can you paint 1,5 pixels, LOL – Gatunox Sep 25 '16 at 20:39
  • 1
    @Gatuox You can in fact paint fractions of pixels. Look up antialiasing techniques. You draw adjacent pixels at varying levels of alpha to approximate the fractions. – Lorne Laliberte Mar 10 '17 at 18:53
  • With App Widgets I get two different results when using `context.getResources().getDisplayMetrics()` and `Resources.getSystem().getDisplayMetrics()` – Pants Aug 31 '18 at 00:51
  • kotlin: fun Context.convertDpToPixel(dp: Float): Float { return dp * (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT) } fun Context.convertPixelToDp(px:Float): Float { return px / (resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT) } – Juan Mendez Dec 16 '19 at 21:18
  • 1) Why do you need `((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT)` when there is already `context.getResources().getDisplayMetrics().density`? 2) Why is pixels in Float type instead of int/ Integer? – ericn Jun 28 '21 at 15:40
314

Preferably put in a Util.java class

public static float dpFromPx(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float pxFromDp(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87
  • 10
    This does not work on all devices! The result of this answer vs that of using TypedValue.applyDimension is not the same on a OnePlus 3T (probably because OnePlus have custom scaling built into the OS). Using TypedValue.applyDimension causes consistent behavior across devices. – Ben De La Haye Aug 20 '18 at 07:52
224
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density equals

  • .75 on ldpi (120 dpi)
  • 1.0 on mdpi (160 dpi; baseline)
  • 1.5 on hdpi (240 dpi)
  • 2.0 on xhdpi (320 dpi)
  • 3.0 on xxhdpi (480 dpi)
  • 4.0 on xxxhdpi (640 dpi)

Use this online converter to play around with dpi values.

EDIT: It seems there is no 1:1 relationship between dpi bucket and density. It looks like the Nexus 5X being xxhdpi has a density value of 2.625 (instead of 3). See for yourself in the Device Metrics.

Zsolt Safrany
  • 13,290
  • 6
  • 50
  • 62
  • 3
    "It looks like the Nexus 5X being xxhdpi has a density value of 2.6 (instead of 3)" - Technically the Nexus 5X is 420dpi and the Nexus 6/6P is 560dpi, neither land directly in one of the standard buckets, just like the Nexus 7 with tvdpi (213dpi). So the site listing those as xxdpi and xxxhdpi is a farce. Your chart IS correct, and those devices will properly scale based one their "special" dpi buckets. – Steven Byle Sep 22 '16 at 16:50
  • Thanks that reminded how to get how many pixels in one dp. It's dpi/160 (for instance, in xxhdpi it's 3 px/dp). – CoolMind Feb 12 '23 at 18:18
144

You can use this .. without Context

public static int pxToDp(int px) {
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

public static int dpToPx(int dp) {
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

As @Stan mentioned .. using this approach may cause issue if system changes density. So be aware of that!

Personally I am using Context to do that. It's just another approach I wanted to share you with

Maher Abuthraa
  • 17,493
  • 11
  • 81
  • 103
  • 15
    You might not want to use this. Documentation for getSystem() - "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)." – Stan Feb 16 '17 at 10:09
  • 1
    Seconding what @Stan is saying: this is dangerous and you shouldn't be using it, especially now when device form factors are becoming so complex. – Saket Aug 05 '19 at 17:50
  • 1
    This is not considering foldables and ChromeOS devices – EpicPandaForce Feb 24 '21 at 09:48
109

If you can use the dimensions XML it's very simple!

In your res/values/dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="thumbnail_height">120dp</dimen>
    ...
    ...
</resources>

Then in your Java:

getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
Tim
  • 41,901
  • 18
  • 127
  • 145
Alex
  • 18,332
  • 10
  • 49
  • 53
  • Since px to dp depends on screen density, I don't know how the OP got 120 in the first place, unless he or she tested the px to dp method on all different screen sizes. – John61590 Jul 21 '17 at 20:35
78

According to the Android Development Guide:

px = dp * (dpi / 160)

But often you'll want do perform this the other way around when you receive a design that's stated in pixels. So:

dp = px / (dpi / 160)

If you're on a 240dpi device this ratio is 1.5 (like stated before), so this means that a 60px icon equals 40dp in the application.

Linga
  • 10,379
  • 10
  • 52
  • 104
Ricardo Magalhães
  • 1,843
  • 15
  • 10
  • 2
    Indhu, You can refer here http://developer.android.com/guide/practices/screens_support.html#dips-pels and http://developer.android.com/reference/android/util/DisplayMetrics.html#density – Sachchidanand Jul 11 '12 at 10:58
  • 12
    160 is constant, bed answer – user25 Aug 28 '16 at 13:15
  • 3
    @user25 Great answer actually. Haven't you read any docs on android screens? 160 is a common constant all over the place when talking about android screen densities. Quote from docs: "medium-density (mdpi) screens (~160dpi). (This is the baseline density)". Come on, man – mykolaj Aug 14 '18 at 11:50
74

Without Context, elegant static methods:

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

public static int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
  • 31
    `Resources.getSystem()` javadoc says "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)." This pretty much says you shouldn't be doing this even if it somehow works. – Austyn Mahoney Jan 07 '14 at 23:33
  • I just read @AustynMahoney's comment and realized this answer isn't as great as I originally thought, but [SO won't let me undo my upvote](http://meta.stackexchange.com/q/80762/302619)! Argh! – Vicky Chijwani Aug 17 '15 at 21:00
64

using kotlin-extension makes it better

fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()

fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()

UPDATE:

Because of displayMetrics is part of global shared Resources, we can use Resources.getSystem()

val Float.toPx get() = this * Resources.getSystem().displayMetrics.density
    
val Float.toDp get() = this / Resources.getSystem().displayMetrics.density
    

    
val Int.toPx get() = (this * Resources.getSystem().displayMetrics.density).toInt()
    
val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()
    

PS: According to @EpicPandaForce's comment:

You should not be using Resources.getSystem() for this, because it does not handle foldables and Chrome OS devices.

beigirad
  • 4,986
  • 2
  • 29
  • 52
48

For DP to Pixel

Create a value in dimens.xml

<dimen name="textSize">20dp</dimen>

Get that value in pixel as:

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
Kapil Rajput
  • 11,429
  • 9
  • 50
  • 65
asadnwfp
  • 733
  • 6
  • 10
47

For anyone using Kotlin:

val Int.toPx: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()

val Int.toDp: Int
    get() = (this / Resources.getSystem().displayMetrics.density).toInt()

Usage:

64.toPx
32.toDp
Gunhan
  • 6,807
  • 3
  • 43
  • 37
  • From the docs for Resource.getSystem(): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)." – HendraWD Sep 05 '18 at 15:35
  • @HendraWD The docs may be confusing, the dimension units it is mentioning is your application level dimens resources. displayMetrics is not an application level resource. It is a system resource and it returns the correct values. This code is working fine on all of my Prod apps. Never had an issue. – Gunhan Sep 05 '18 at 15:58
  • I like this solution, but I initially read the logic as backwards. I was wanting to type the dp value and say `myVal.dp`. If you think what I was wanting to do reads nicer, then you'll want to swap the divide and multiply logic. Also I think it is slightly better to use `roundToInt()` instead of `toInt()` here. – Adam Johns Mar 24 '21 at 19:16
  • @AdamJohns Because all the View related functions use Pixels as arguments, I though 64.toPx would make more sense. I read it as 64 to -be converted- to pixels. But feel free to change the order and names as you wish. At the end the important part is if you multiply the value by density or not. – Gunhan Mar 24 '21 at 21:34
  • You should not be using Resources.getSystem() for this. – EpicPandaForce May 14 '22 at 10:02
41

You can therefore use the following formulator to calculate the right amount of pixels from a dimension specified in dp

public int convertToPx(int dp) {
    // Get the screen's density scale
    final float scale = getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    return (int) (dp * scale + 0.5f);
}
tabjsina
  • 1,582
  • 15
  • 26
neeraj t
  • 4,654
  • 2
  • 27
  • 30
  • 4
    This converts dp to pixels but you called your method `convertToDp`. – Qwertie Jul 03 '12 at 22:33
  • 5
    +0.5f is explain here --> http://developer.android.com/guide/practices/screens_support.html#dips-pels . It's used to round up to the nearest integer. – Bae Aug 05 '14 at 09:29
  • the only right answer. you could add the source https://developer.android.com/guide/practices/screens_support.html#screen-independence – user25 Aug 28 '16 at 13:41
  • 1
    http://web.archive.org/web/20140808234241/http://developer.android.com/guide/practices/screens_support.html#dips-pels for a link that still has the content in question – caw Jun 28 '19 at 00:53
35

There is a default util in android SDK: http://developer.android.com/reference/android/util/TypedValue.html

float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
Yan
  • 1,569
  • 18
  • 22
  • You should be using this one. As a bonus it will also do SP. – Mark Renouf Mar 27 '14 at 00:35
  • 2
    `resultPix` should be of type int. `int resultPix = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())` – vovahost Feb 11 '15 at 17:22
25

Kotlin

fun convertDpToPixel(dp: Float, context: Context): Float {
    return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

fun convertPixelsToDp(px: Float, context: Context): Float {
    return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

Java

public static float convertDpToPixel(float dp, Context context) {
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

public static float convertPixelsToDp(float px, Context context) {
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
19

This should give you the conversion dp to pixels:

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

This should give you the conversion pixels to dp:

public static int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Saravanabalagi Ramachandran
  • 8,551
  • 11
  • 53
  • 102
Venki WAR
  • 1,997
  • 4
  • 25
  • 38
12

Probably the best way if you have the dimension inside values/dimen is to get the dimension directly from getDimension() method, it will return you the dimension already converted into pixel value.

context.getResources().getDimension(R.dimen.my_dimension)

Just to better explain this,

getDimension(int resourceId) 

will return the dimension already converted to pixel AS A FLOAT.

getDimensionPixelSize(int resourceId)

will return the same but truncated to int, so AS AN INTEGER.

See Android reference

Lorenzo Barbagli
  • 1,241
  • 2
  • 16
  • 34
9

like this:

public class ScreenUtils {

    public static float dpToPx(Context context, float dp) {
        if (context == null) {
            return -1;
        }
        return dp * context.getResources().getDisplayMetrics().density;
    }

    public static float pxToDp(Context context, float px) {
        if (context == null) {
            return -1;
        }
        return px / context.getResources().getDisplayMetrics().density;
    }
}

dependent on Context, return float value, static method

from: https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15

Trinea
  • 649
  • 8
  • 10
9

Kotlin:

fun spToPx(ctx: Context, sp: Float): Float {
    return sp * ctx.resources.displayMetrics.scaledDensity
}

fun pxToDp(context: Context, px: Float): Float {
    return px / context.resources.displayMetrics.density
}

fun dpToPx(context: Context, dp: Float): Float {
    return dp * context.resources.displayMetrics.density
}

Java:

public static float spToPx(Context ctx,float sp){
    return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}

public static float pxToDp(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float dpToPx(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}
Max Base
  • 639
  • 1
  • 7
  • 15
younes
  • 742
  • 7
  • 8
7

In case you developing a performance critical application, please consider the following optimized class:

public final class DimensionUtils {

    private static boolean isInitialised = false;
    private static float pixelsPerOneDp;

    // Suppress default constructor for noninstantiability.
    private DimensionUtils() {
        throw new AssertionError();
    }

    private static void initialise(View view) {
        pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f;
        isInitialised = true;
    }

    public static float pxToDp(View view, float px) {
        if (!isInitialised) {
            initialise(view);
        }

        return px / pixelsPerOneDp;
    }

    public static float dpToPx(View view, float dp) {
        if (!isInitialised) {
            initialise(view);
        }

        return dp * pixelsPerOneDp;
    }
}
Pavel
  • 4,912
  • 7
  • 49
  • 69
7
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
Sibin
  • 511
  • 6
  • 10
  • 2
    Is this not just the same as what's covered in many of the other answers to this question? – TZHX Apr 22 '15 at 08:56
6

This is how it works for me:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int  h = displaymetrics.heightPixels;
float  d = displaymetrics.density;
int heightInPixels=(int) (h/d);

You can do the same for the width.

Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
6

to convert Pixels to dp use the TypedValue .

As the documentation mentioned : Container for a dynamically typed data value .

and use the applyDimension method :

public static float applyDimension (int unit, float value, DisplayMetrics metrics) 

which Converts an unpacked complex data value holding a dimension to its final floating point value like the following :

Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());

Hope that Helps .

  • This converts pixels to pixels. applyDimension always returns pixels (it's meant for converting dp -> pixels, doesn't work the other way around unfortunately.) – phreakhead Aug 12 '22 at 18:47
6

A lot of great solutions above. However, the best solution I found is google's design:

https://design.google.com/devices/

Density

Kai Wang
  • 3,303
  • 1
  • 31
  • 27
6

More elegant approach using kotlin's extension function

/**
 * Converts dp to pixel
 */
val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()

/**
 * Converts pixel to dp
 */
val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()

Usage:

println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
Saeed Masoumi
  • 8,746
  • 7
  • 57
  • 76
  • Love the use of extension here. I read the functions as "convert to `function name`" which I realize is backwards in this case. To clarify each function's intent, the names of the functions could be updated to read dpToPx and pxToDp, respectively. – Maxwell Aug 17 '17 at 17:04
  • 1
    From the docs for Resource.getSystem(): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)." – HendraWD Sep 05 '18 at 15:35
  • You should not be using Resources.getSystem() for this. – EpicPandaForce May 14 '22 at 10:03
5

To convert dp to pixel

public static int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        dp,resource.getDisplayMetrics()
    );
}

To convert pixel to dp.

public static float px2dp(Resources resource, float px)  {
    return (float)TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_PX,
        px,
        resource.getDisplayMetrics()
    );
}

where resource is context.getResources().

Manaus
  • 407
  • 5
  • 9
Prince Gupta
  • 153
  • 2
  • 10
4

You should use dp just as you would pixels. That's all they are; display independent pixels. Use the same numbers you would on a medium density screen, and the size will be magically correct on a high density screen.

However, it sounds like what you need is the fill_parent option in your layout design. Use fill_parent when you want your view or control to expand to all the remaining size in the parent container.

Michael Lowman
  • 3,000
  • 1
  • 20
  • 34
  • actually my problem is my application is coded for high density screen and now it needs to be converted to low density screen.. – Indhu Jan 06 '11 at 04:44
  • modify your pixels for a medium density screen (you can set up a medium density screen in the emulator) and replace the pixel with dp. However, more flexible applications can be made using fill_parent and multiple layouts. – Michael Lowman Jan 06 '11 at 12:20
  • Finally, i had no option but to change all the px to dp manually.. :( – Indhu Jan 12 '11 at 13:18
  • 1
    At least next time you'll use dp first and won't have to change anything :) Although it should be possible to use layouts that don't require absolute positioning for most things. – Michael Lowman Jan 12 '11 at 13:22
  • Since it was my first app.. i made this mistake... i ll never do it again...:) – Indhu Jan 12 '11 at 13:59
4

PX and DP are different but similar.

DP is the resolution when you only factor the physical size of the screen. When you use DP it will scale your layout to other similar sized screens with different pixel densities.

Occasionally you actually want pixels though, and when you deal with dimensions in code you are always dealing with real pixels, unless you convert them.

So on a android device, normal sized hdpi screen, 800x480 is 533x320 in DP (I believe). To convert DP into pixels /1.5, to convert back *1.5. This is only for the one screen size and dpi, it would change depending on design. Our artists give me pixels though and I convert to DP with the above 1.5 equation.

Kapil Rajput
  • 11,429
  • 9
  • 50
  • 65
HaMMeReD
  • 2,440
  • 22
  • 29
3

If you want Integer values then using Math.round() will round the float to the nearest integer.

public static int pxFromDp(final float dp) {
        return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
    }
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
3

The best answer comes from the Android framework itself: just use this equality...

public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
    final float scale = display_metrics.density;
    return (int) (dps * scale + 0.5f);
}

(converts dp to px)

JarsOfJam-Scheduler
  • 2,809
  • 3
  • 31
  • 70
3
private fun toDP(context: Context,value: Int): Int {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(),context.resources.displayMetrics).toInt()
}
Alexander
  • 576
  • 5
  • 17
2

This workds for me (C#):

int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
1

For Xamarin.Android

float DpToPixel(float dp)
{
    var resources = Context.Resources;
    var metrics = resources.DisplayMetrics;
    return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}

Making this a non-static is necessary when you're making a custom renderer

mr5
  • 3,438
  • 3
  • 40
  • 57
0

The developer docs provide an answer on how to convert dp units to pixel units:

In some cases, you will need to express dimensions in dp and then convert them to pixels. The conversion of dp units to screen pixels is simple:

px = dp * (dpi / 160)

Two code examples are provided, a Java example and a Kotlin example. Here is the Java example:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

The Kotlin example:

// The gesture threshold expressed in dp
private const val GESTURE_THRESHOLD_DP = 16.0f
...
private var mGestureThreshold: Int = 0
...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Get the screen's density scale
    val scale: Float = resources.displayMetrics.density
    // Convert the dps to pixels, based on density scale
    mGestureThreshold = (GESTURE_THRESHOLD_DP * scale + 0.5f).toInt()

    // Use mGestureThreshold as a distance in pixels...
}

The Java method that I created from the Java example works well:

/**
 * Convert dp units to pixel units
 * https://developer.android.com/training/multiscreen/screendensities#dips-pels
 *
 * @param dip input size in density independent pixels
 *            https://developer.android.com/training/multiscreen/screendensities#TaskUseDP
 *
 * @return pixels
 */
private int dpToPixels(final float dip) {
    // Get the screen's density scale
    final float scale = this.getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    final int pix = Math.round(dip * scale + 0.5f);
    
    if (BuildConfig.DEBUG) {
        Log.i(DrawingView.TAG, MessageFormat.format(
                "Converted: {0} dip to {1} pixels",
                dip, pix));
    }
    
    return pix;
}

Several of the other answers to this question provide code that is similar to this answer, but there was not enough supporting documentation in the other answers for me to know if one of the other answers was correct. The accepted answer is also different than this answer. I thought the developer documentation made the Java solution clear.

There is also a solution in Compose. Density in Compose provides a one line solution for the conversions between device-independent pixels (dp) and pixels.

val sizeInPx = with(LocalDensity.current) { 16.dp.toPx() }
-1

To convert dp to px this code can be helpful :

public static int dpToPx(Context context, int dp) {
       final float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
    }
Bipin Bharti
  • 1,034
  • 2
  • 14
  • 27
Son Nguyen
  • 79
  • 3
-3
((MyviewHolder) holder).videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(final MediaPlayer mediaPlayer) {
        mediaPlayer.setLooping(true);
        ((MyviewHolder) holder).spinnerView.setVisibility(View.GONE);
        mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
           @Override
           public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
               /*
               * add media controller
               */
               MediaController controller = new MediaController(mContext);
               float density = mContext.getResources().getDisplayMetrics().density;
               float px = 55 * density;
               // float dp = somePxValue / density;
               controller.setPadding(0, 0, 0, (int) (px));
               ((MyviewHolder) holder).videoView.setMediaController(controller);
            }
        });
    }
});
Manaus
  • 407
  • 5
  • 9
Manthan Patel
  • 1,784
  • 19
  • 23
  • I think your post needs some extra words and a little bit of formatting, at one point i thought i am on completely different question. – RickertBrandsen Jan 04 '22 at 12:38