button.setLayoutParams(new GridView.LayoutParams(65, 65));
According to the docs the units for the width and height (both 65 in the above) are “pixels”. How do you force this to be device independent pixels, or “dp”?
You’ll have to convert it from dps to pixels using the display scale factor.
final float scale = getContext().getResources().getDisplayMetrics().density; int pixels = (int) (dps * scale + 0.5f);
I know this is an old question however I’ve found a much neater way of doing this conversion.
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)
Looking at your requirement, there is alternate solution as well. It seems you know the dimensions in dp at compile time, so you can add a dimen entry in the resources. Then you can query the dimen entry and it will be automatically converted to pixels in this call:
final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);
And your dimens.xml will have:
Extending this idea, you can simply store the value of 1dp or 1sp as a dimen entry and query the value and use it as a multiplier. Using this approach you will insulate the code from the math stuff and rely on the library to perform the calculations.
simplest way(and even works from api 1) that tested is:
Retrieve a dimensional for a particular resource ID for use as a size
in raw pixels. This is the same as getDimension(int), except the
returned value is converted to integer pixels for use as a size. A
size conversion involves rounding the base value, and ensuring that a
non-zero base value is at least one pixel in size.
Yes it rounding the value but it’s not very bad(just in odd values on hdpi and ldpi devices need to add a little value when ldpi is not very common)
I tested in a xxhdpi device that converts 4dp to 16(pixels) and that is true.