Programmatically set height on LayoutParams as density-independent pixels
AndroidAndroid LayoutAndroid Problem Overview
Is there any way to set the height/width of a LayoutParams as density-independent pixels (dp)? It looks like the height/width, when set programmatically, are in pixels and not dp.
Android Solutions
Solution 1 - Android
You need to convert your dip value into pixels:
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());
For me this does the trick.
Solution 2 - Android
public static int getDPI(int size, DisplayMetrics metrics){
return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
}
Call the function like this,
DisplayMetrics metrics;
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heigh = getDPI(height or width, metrics);
Solution 3 - Android
Since it may be used multiple times:
public static int convDpToPx(Context context, float dp) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
I found it more practical to use the conversion rate, as usally more than one value has to be converted. Since the conversion rate does not change, it saves a bit of processing time.
/**
* Get conversion rate from dp into px.<br>
* E.g. to convert 100dp: px = (int) (100 * convRate);
* @param context e.g. activity
* @return conversion rate
*/
public static float convRateDpToPx(Context context) {
return context.getResources().getDisplayMetrics().densityDpi / 160f;
}
Solution 4 - Android
Here is my snippet:
public class DpiUtils {
public static int toPixels(int dp, DisplayMetrics metrics) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}
}
where DisplayMetrics metrics = getResources().getDisplayMetrics()
Solution 5 - Android
The answered solution didn't work for me, the height of the view was still off. I ended up with this, which works well:
protected int dp2px(int dp){
final float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
And if you want the other way round, pixels to dp ...
protected float px2dp(float px){
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float dp = px / (metrics.densityDpi / 160f);
return Math.round(dp);
}