Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to specify dimensions in DIP from Java code?

There is an existing utility method built called TypedValue.applyDimensions(int, float, DisplayMetrics) that does this.

Here's how to use it:

// returns the number of pixels for 123.4dip
int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
                     (float) 123.4, getResources().getDisplayMetrics());

There's a list of other types that you can use with it including COMPLEX_UNIT_SP, COMPLEX_UNIT_PT all found in the page I linked above. If you exclude the (int) typecast, you'll get the floating point number.

I encountered the same problem and found this through poking around the code.


That is the correct formula there. Although DisplayMetrics.density is not a static member, so, according to the same document you alluded to, correct usage is:

// Maybe store this in a static field?
final float SCALE = getContext().getResources().getDisplayMetrics().density;

// Convert dips to pixels
float valueDips = 16.0f;
int valuePixels = (int)(valueDips * SCALE + 0.5f); // 0.5f for rounding

Using the display metrics density field, you can get a scaling factor to convert to/from dips. Use the Math.round method to convert from a float to an int without needing a cast or adding 0.5

// Converting dips to pixels
float dips = 20.0f;
float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = Math.round(dips * scale);

// Converting pixels to dips
int pixels = 15;
float scale = getContext().getResources().getDisplayMetrics().density;
float dips = pixels / scale;

I think the best way is not to define any dimensions in code, but use the values/dimens.xml file instead. You can always define your dimension in the desired unit like:

<dimen name="my_layout_height">120dp</dimen>

and then refer to this in your Activity like:

getResources().getDimensions(R.dimen.my_layout_height);

This would return pixels after doing the necessary conversions. And also of course you can refer to this in your other XMLs like:

android:layout_width="@dimen/my_layout_height"