Android и настройка ширины и высоты программно в единицах dp

Я делаю:

button.setLayoutParams(new GridView.LayoutParams(65, 65));

В соответствии с документами единицы для ширины и высоты (оба из 65 в приведенном выше) являются "пикселями". Как заставить это быть независимыми от устройства пикселями или "dp"?

Ответ 1

Вам нужно будет преобразовать его из dps в пиксели с использованием масштабного коэффициента отображения.

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);

Ответ 2

Я знаю, что это старый вопрос, однако я нашел более аккуратный способ сделать это преобразование.

Java

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());

Котлин

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)

Ответ 3

Глядя на ваше требование, есть альтернативное решение. Кажется, вы знаете размеры в dp во время компиляции, поэтому вы можете добавить запись в ресурсы. Затем вы можете запросить запись dimen, и она будет автоматически преобразована в пиксели в этом вызове:

final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);

И ваш dimens.xml будет иметь:

<dimen name="dimen_entry_in_dp">72dp</dimen>

Расширяя эту идею, вы можете просто сохранить значение 1dp или 1sp в качестве элемента dimen и запросить значение и использовать его как множитель. Используя этот подход, вы изолируете код от математического материала и полагаетесь на библиотеку для выполнения вычислений.

Ответ 4

Простейший способ (и даже работающий с API 1), который был протестирован:

getResources().getDimensionPixelSize(R.dimen.example_dimen);

Из документации:

Получить размер для конкретного идентификатора ресурса для использования в качестве размера в необработанных пикселях. Это то же самое, что и getDimension (int), за исключением возвращаемое значение преобразуется в целочисленные пиксели для использования в качестве размера. преобразование размера включает округление базового значения и обеспечение того, чтобы ненулевое базовое значение имеет размер не менее одного пикселя.

Да, это округляет значение, но это не очень плохо (просто в нечетных значениях на устройствах hdpi и ldpi нужно добавить небольшое значение, когда ldpi не очень распространено) Я проверил на устройстве xxhdpi, которое конвертирует 4dp в 16 (пикселей), и это правда.