Does setWidth(int pixels) use dip or px?
Asked Answered
I

7

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.

Ischium answered 9/3, 2010 at 3:29 Comment(0)
B
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()));
Billibilliard answered 9/3, 2010 at 5:6 Comment(7)
You can also call nbDips * getResources().getDisplayMetrics().densityRetrench
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. :)Billibilliard
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.Retrench
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 expectedOden
The only solution I found for px to pt conversion, very nice.Savory
Resources.getSystem().getDisplayMetrics().denisty in case you are in a Util class that has no context. Got this from hereMouthwatering
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.Hightest
H
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.

Heterochromatic answered 17/2, 2013 at 14:15 Comment(3)
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.Laverne
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 :)Flowerless
@Flowerless yes I see what you mean so I've updated the wording slightlyHeterochromatic
P
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());
Paginal answered 1/11, 2014 at 6:35 Comment(0)
M
6
float dps = 100;
float pxs = dps * getResources().getDisplayMetrics().density;

Source (@Romain Guy)

Myke answered 14/2, 2015 at 16:13 Comment(0)
I
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());
    }
Incensory answered 27/8, 2019 at 12:27 Comment(2)
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"...)Icarian
@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.Incensory
M
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()
}
Markhor answered 6/7, 2021 at 10:22 Comment(0)
A
0

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

Albescent answered 9/3, 2010 at 4:33 Comment(2)
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?Ischium
Not directly, you have to convert yourself using DisplayMetrics.density.Retrench

© 2022 - 2024 — McMap. All rights reserved.