102

Does setWidth(int pixels) use device independent pixel or physical pixel as unit? For example, does setWidth(100) set the a view's width to 100 dips or 100 pxs?

Thanks.

Francisco Alvarado
  • 2,815
  • 2
  • 26
  • 51
user256239
  • 17,717
  • 26
  • 77
  • 89

7 Answers7

227

It uses pixels, but I'm sure you're wondering how to use dips instead. The answer is in TypedValue.applyDimension(). Here's an example of how to convert dips to px in code:

// Converts 14 dip into its equivalent px
Resources r = getResources();
int px = Math.round(TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP, 14,r.getDisplayMetrics()));
robguinness
  • 16,266
  • 14
  • 55
  • 65
Dan Lew
  • 85,990
  • 32
  • 182
  • 176
  • 67
    You can also call nbDips * getResources().getDisplayMetrics().density – Romain Guy Mar 09 '10 at 05:08
  • 9
    In fact, that's exactly what TypedValue.applyDimension() does. I considered posting that, but I like going through the API in case anything ever changes... though I guess it's safe to use that method if you give it the okay. :) – Dan Lew Mar 09 '10 at 05:15
  • 13
    The applyDimension() version executes more code and it a bit more difficult to read I find. FWIW, the line I posted is what we actually use all over the place in the framework and standard apps. – Romain Guy Mar 09 '10 at 05:25
  • 1
    Hi, i tried the above two examples and it doesnt seem to calculate the pixels correctly. instead, it returns me the exact value i specify in my view: android:layout_width="50dip" in my case. it will return me 50 the exact value in the xml file. i then checked this in the app and as expected, the value is incorrect and draws the view too large then expected – Jono Jan 17 '11 at 15:15
  • The only solution I found for px to pt conversion, very nice. – A-Live Dec 13 '12 at 13:42
  • `Resources.getSystem().getDisplayMetrics().denisty` in case you are in a Util class that has no context. Got this from [here](https://stackoverflow.com/a/9563438/8383332) – Soon Santos Sep 26 '18 at 20:15
  • its weird when your team also has web developers. My Senior gives me a size of 50 * 50 px, so he is expecting me to have a 50*50 size button(" the size of a launcher icon"). But in android, its 50*50 dp , so he actually means he is giving me 50*50 dp size and i have to convert it into pixels which is a relatively bigger value. – ansh sachdeva Sep 12 '19 at 07:30
28

The correct way to obtain a constant number of DIPs in code is to create a resources XML file containing dp values a bit like:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="image_width">100dp</dimen>
    <dimen name="image_height">75dp</dimen>
</resources>

Then refer to the resource in your code like so:

float width = getResources().getDimension(R.dimen.image_width));
float height = getResources().getDimension(R.dimen.image_height));

The float you have returned will be scaled accordingly for the pixel density of the device and so you don't need to keep replicating a conversion method throughout your application.

SDJMcHattie
  • 1,690
  • 1
  • 15
  • 21
  • In my situation, this solution works best where I have an custom dialog which has a listview and a want to set the width of the Header Labels and columns in the ListView to the same width. – Wayne Phipps Jun 07 '13 at 11:02
  • Your first sentence is kinda funny, you are basically saying that creating an XML file is the proper way to *"specify [something] in code"*. Well I think you're merely using the constant in code not specifying it :) – Joffrey Jun 19 '14 at 08:35
  • @Joffrey yes I see what you mean so I've updated the wording slightly – SDJMcHattie Jul 10 '14 at 14:37
10

Method setWidth(100), set 100 px as width(not in dp).So you may face width varying problems on different android phones.So use measurement in dp instead of pixels.Use the below code to get measurement in dp of sample width=300px and height=400px.

int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, getResources().getDisplayMetrics());

int Height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 400, getResources().getDisplayMetrics());
Nidhin
  • 1,818
  • 22
  • 23
6
float dps = 100;
float pxs = dps * getResources().getDisplayMetrics().density;

Source (@Romain Guy)

Community
  • 1
  • 1
pomber
  • 23,132
  • 10
  • 81
  • 94
2

Based on above answers which works fine to me, i generate some helper methods, just add them in your utils to use them in whole project.

   // value in DP
   public static int getValueInDP(Context context, int value){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, context.getResources().getDisplayMetrics());
    }

    public static float getValueInDP(Context context, float value){
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, context.getResources().getDisplayMetrics());
    }

    // value in PX
    public static int getValueInPixel(Context context, int value){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, value, context.getResources().getDisplayMetrics());
    }

    public static float getValueInPixel(Context context, float value){
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, value, context.getResources().getDisplayMetrics());
    }
Abhishek Garg
  • 3,092
  • 26
  • 30
  • from the above answers, I think you may have reversed px and dp methods. if you consider the accepted answer for instance, it has the exact same code as your first method, but in the answer it is supposed to return a value in PX and not in DP as in your code. (I wanted to edit, but SO tells me "Suggested edit queue is full"...) – V4karian Nov 12 '20 at 10:43
  • @V4karian Hey thanks for your comment, but i want to let you know is that, i have added methods for both DP and Pixel, based on requirement you can use either of one. – Abhishek Garg Nov 23 '20 at 15:27
1

It uses pixels. here's a Kotlin extension function to convert pixels to dp

fun Context.pxToDp(value: Float):Int{
    val r: Resources = resources
    return TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, value, r.displayMetrics
    ).roundToInt()
}
Kasun Thilina
  • 1,523
  • 2
  • 14
  • 20
0

Pixels of course, the method is asking for pixels as parameter.

Brais Gabin
  • 5,827
  • 6
  • 57
  • 92
Josnidhin
  • 12,469
  • 9
  • 42
  • 61
  • 1
    If it is in layout xml file, we can specify android:layout_width="100dip" or android:layout_width="100px". In the source code, we can't specify the width of a layout as 100dip? – user256239 Mar 09 '10 at 05:05
  • Not directly, you have to convert yourself using DisplayMetrics.density. – Romain Guy Mar 09 '10 at 05:10