Android и установка ширины и высоты программно в дп

304

Я делаю:

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

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

SK9
источник

Ответы:

541

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

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);
Робби Понд
источник
111
Правильное преобразование: (int) (dps * scale + 0.5f). Это формула, которую мы используем в рамках.
Ромен Гай
8
Формула в документах. Для дальнейшего чтения, перейдите в раздел 3 из developer.android.com/guide/practices/...
SK9
34
@ RomainGuy, не могли бы вы добавить функцию API в API для конвертации dpв px? Спасибо.
Алик Эльзин-килака
3
что здесь дпс? я получаю "dps не может быть разрешена переменная" ошибка? какой тип "дпс" нужно декларировать ??
Дипак
5
Переменная «dps» - это входное значение, которое вы хотите преобразовать.
Робби Понд,
233

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

Ява

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

Котлин

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)
drspaceboo
источник
8
Хорошо сделано, чтобы узнать, как это сделать. Я не фанат повторения формулы в нескольких местах! Спасибо.
Дарренп
2
Если нет, то создайте функцию с формулой
Sayka 9.10.15
1
@Kenobi Это делает преобразование для вас из DP в PX. Выше 65приведено значение DP, которое вы хотите преобразовать в PX
drspaceboo
7
Это должен быть принятый ответ, а не текущий, где эти числа (0.5) магически исходят из
ниоткуда
1
@ Johny19 0.5 не волшебство. Это просто, как округлить число с плавающей запятой до ближайшего целого числа вместо усечения его. Смотрите мой комментарий на ответ Робби Понд для более подробной информации.
MarredCheese
38

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

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

И ваши измерения. Xml будут иметь:

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

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

vine'th
источник
Обратите внимание, что возвращаемое значение на самом деле является int, поэтому оно передается в float.
CorayThan
Это плохой ответ, потому что быть динамичным
Johny19
37

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

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

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

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

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

Дэвид
источник