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

Я хотел бы загрузить значение как есть. У меня два 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"...

11 ответов

Решение

В моем измерении. 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

Context.getResources().getDimension(int id);

Для тех, кому просто нужно сэкономить 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);

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

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

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

Используйте расширение 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

Вот лучшее решение, не связанное с двойным преобразованием из dp в px, а затем из px в dp:

В Котлине

      fun Resources.getRawDimensionInDp(@DimenRes dimenResId: Int): Float {
    val value = TypedValue()
    getValue(dimenResId, value, true)
    return TypedValue.complexToFloat(value.data)
}
// Usage: 
resources.getRawDimensionInDp(R.dimen.my_dimen_id)

В Java

      public class ResourcesUtil {
    static Float getRawDimensionInDp(Resources resources, @DimenRes int dimenResId) {
        TypedValue value = new TypedValue();
        resources.getValue(dimenResId, value, true);
        return TypedValue.complexToFloat(value.data);
    }
}

// Usage: 
ResourcesUtil.getRawDimensionInDp(resources, R.dimen.my_dimen_id);

Вы можете написать целое число в файле XML также..
Вы видели [это] http://developer.android.com/guide/topics/resources/more-resources.html? использовать как.

 context.getResources().getInteger(R.integer.height_pop);

Две вспомогательные функции, которые я написал для этого в kotlin

      /**
 * Gets the float value defined in dimens
 * Define float value as following
 * Example:
 * <item name="example" format="float" type="dimen">1.0</item>
 */
fun Resources.getFloatDimension(dimensResourceId: Int): Float {
    val outValue = TypedValue()
    this.getValue(dimensResourceId, outValue, true)
    return outValue.float
}

/**
 * Gets the dp value defined in dimens
 * Example:
 * <dimen name="example">12dp</dimen>
 *
 * Will return 12
 */
fun Resources.getDimensionInDp(dimensResourceId: Int): Int {
    return (getDimension(dimensResourceId) / displayMetrics.density).toInt()
}
    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-единиц) - это простое решение для правильного изменения размеров вида в макете для разных плотностей экрана. Другими словами, он обеспечивает согласованность с реальными размерами ваших элементов пользовательского интерфейса на разных устройствах.

ПВ

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

Если вы просто хотите динамически изменять размер шрифта, вы можете:

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.tutorial_cross_marginTop))

В качестве ответа @achie вы можете получить dp из sizes.xml следующим образом:

val dpValue = (resources.getDimension(R.dimen.tutorial_cross_marginTop)/ resources.displayMetrics.density).toInt()

или получить такой sp

val spValue = (resources.getDimension(R.dimen.font_size)/ resources.displayMetrics.scaledDensity).toInt()

О Resources.java #{getDimension}

    /**
     * Retrieve a dimensional for a particular resource ID.  Unit 
     * conversions are based on the current {@link DisplayMetrics} associated
     * with the resources.
     * 
     * @param id The desired resource identifier, as generated by the aapt
     *           tool. This integer encodes the package, type, and resource
     *           entry. The value 0 is an invalid identifier.
     * 
     * @return Resource dimension value multiplied by the appropriate 
     * metric.
     * 
     * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
     *
     * @see #getDimensionPixelOffset
     * @see #getDimensionPixelSize
     */

Значение параметра ресурса, умноженное на соответствующий

Другие вопросы по тегам