Загрузить значение измерения из res / values ​​/ dimension.xml из исходного кода

337

Я хотел бы загрузить значение как есть. У меня есть два dimension.xmlфайла, один в /res/values/dimension.xmlи другой в /res/values-sw360dp/dimension.xml.

Из исходного кода я хотел бы сделать что-то вроде

getResources().getDimension(R.dimen.tutorial_cross_marginTop);

Это работает, но полученное значение умножается на коэффициент плотности экрана (1,5 для hdpi, 2,0 для xhdpi и т. Д.).

Я тоже пытался сделать

getResources().getString(R.dimen.tutorial_cross_marginTop);

Это будет работать в принципе, но я получаю строку, которая заканчивается "dip" ...

Эктор Худес Сапена
источник
1
Интересно, если это ошибка в Android, так как у ресурсов есть метод, getDimensionPixelSize(int id)который точно указывает, что он возвращается в пикселях, поэтому getDimension(int id)должен возвращаться в dp (независимые от зависимостей единицы), который был бы готов к использованию, например, с ViewsetPadding
Paul Verest

Ответы:

812

В моем измерении. XML

<dimen name="test">48dp</dimen>

В коде, если я делаю

int valueInPixels = (int) getResources().getDimension(R.dimen.test)

это вернет 72, которые в качестве состояния документа умножаются на плотность текущего телефона (48dp x 1,5 в моем случае)

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

Получить измерение для определенного идентификатора ресурса. Преобразование единиц основано на текущих DisplayMetrics, связанных с ресурсами.

так что если вам нужно точное значение dp, как в xml, просто разделите его на плотность DisplayMetrics

int dp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().density)

дп сейчас будет 48

AndroidGecko
источник
3
Я думаю, что документация здесь особенно неясна. «Преобразование единиц основано на текущих DisplayMetrics, связанных с ресурсами». когда все, что они хотят сказать, это то, что они конвертируют в пиксели.
Триларион
Если вы, по сути, собираетесь отказаться от множителя отображаемых метрик, вы также можете просто определить свое измерение в px. <измерение name = "тест"> 48px </ dimension>. getDimension (R.dimen.test) вернется 48.
Майкл Петерсон
Не работает для меня: stackoverflow.com/questions/55972518/…
Алекс
@Trilarion Они не просто конвертируются в пиксели. Они говорят, что dpдаст масштабированное значение пикселя относительно масштаба объекта ресурса, использованного для его получения. Как только вы получите различные способы получения ресурсов, это будет более актуально. Для простоты вы можете думать об этом как о масштабе экрана. Также есть spили пиксели относительно размера системного текста, и px, или, пиксели напрямую. Каждый отличается и имеет разные цели.
Заброшенная корзина
18

В Resourceклассе также есть метод getDimensionPixelSize (), который, я думаю, подойдет вам.

Овидиу Латку
источник
24
Это не верно! преобразование метрик также происходит в том getDimensionPixelSize()случае, если вы можете ссылаться на документы, в которых оно четко указано. Возвраты Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Мухаммад Бабар
Это не верно. Преобразование метрик также происходит с использованием этого метода.
Майкл Петерсон
14

Для тех, кому просто нужно сохранить какое-то intзначение в ресурсах, вы можете сделать следующее.

integers.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="default_value">100</integer>
</resources> 

Код

int defaultValue = getResources().getInteger(R.integer.default_value);
Suragch
источник
2
Спасибо вам за это, это было больше того, что я искал, хотя, возможно, и не для других, но это решение на самом деле дало мне некоторое представление о других областях моего кода
JamisonMan111
11

Вы можете использовать getDimensionPixelOffset () вместо getDimension, чтобы вам не приходилось приводить к int.

int valueInPixels = getResources().getDimensionPixelOffset(R.dimen.test)
Джонни Райт
источник
2
    This works but the value I get is multiplied times the screen density factor
  (1.5 for hdpi, 2.0 for xhdpi, etc).

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

Плотно-независимый пиксель (dp)

Виртуальный пиксельный модуль, который следует использовать при определении макета пользовательского интерфейса, чтобы выражать размеры или положение макета независимым от плотности способом. Плотно-независимый пиксель эквивалентен одному физическому пикселю на экране с разрешением 160 точек на дюйм, который является базовой плотностью, принятой системой для экрана «средней» плотности. Во время выполнения система прозрачно обрабатывает любое масштабирование модулей dp, если это необходимо. based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels.Вы всегда должны использовать модули dp при определении пользовательского интерфейса вашего приложения, чтобы обеспечить правильное отображение вашего пользовательского интерфейса на экранах с различной плотностью.

Я думаю, что это хорошо, чтобы изменить значение в соответствии с разрешением, но если вы не хотите делать это, укажите это в px .......

обратитесь по этой ссылке

согласно этому

дп

Плотно-независимые пиксели - абстрактная единица измерения, основанная на физической плотности экрана. Эти единицы относятся к экрану 160 точек на дюйм (точек на дюйм), на котором 1dp примерно равен 1px. When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down.Отношение dp к пикселю будет меняться в зависимости от плотности экрана, но не обязательно в прямой пропорции. Использование dp-единиц (вместо px-единиц) - это простое решение для правильного изменения размеров вида в макете для разных плотностей экрана. Другими словами, он обеспечивает согласованность реальных размеров ваших элементов пользовательского интерфейса на разных устройствах.

ПВ

Пиксели - соответствует фактическим пикселям на экране. Эта единица измерения не рекомендуется, потому что фактическое представление может варьироваться в зависимости от устройства; Каждое устройство может иметь различное количество пикселей на дюйм и может иметь больше или меньше доступных пикселей на экране.

Дирэш Сингх
источник
2

Используйте расширение Kotlin

Вы можете добавить расширение, чтобы упростить этот процесс. Это позволяет вам просто позвонить, context.dp(R.dimen. tutorial_cross_marginTop)чтобы получить значение Float

fun Context.px(@DimenRes dimen: Int): Int = resources.getDimension(dimen).toInt()

fun Context.dp(@DimenRes dimen: Int): Float = px(dimen) / resources.displayMetrics.density

Если вы хотите обрабатывать это без контекста, вы можете использовать Resources.getSystem():

val Int.dp get() = this / Resources.getSystem().displayMetrics.density // Float

val Int.px get() = (this * Resources.getSystem().displayMetrics.density).toInt()

Например, на устройстве xhdpi используйте 24.dpдля получения 12.0 или 12.pxдля получения 24

Gibolt
источник