繁体   English   中英

从源代码的 res/values/dimension.xml 加载维度值

[英]Load dimension value from res/values/dimension.xml from source code

我想按原样加载值。 我有两个dimension.xml文件,一个在/res/values/dimension.xml中,另一个在/res/values-sw360dp/dimension.xml中。

从源代码我想做类似的事情

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

这有效,但我得到的值乘以屏幕密度因子(hdpi 为 1.5,xhdpi 为 2.0,等等)。

我也试过

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

这原则上可行,但我得到一个以“dip”结尾的字符串......

在我的 dimens.xml 我有

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

在代码中如果我这样做

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

这将返回 72 作为文档状态乘以当前手机的密度(在我的情况下为 48dp x 1.5)

完全按照文档状态:

检索特定资源 ID 的维度。 单位转换基于与资源关联的当前 DisplayMetrics。

因此,如果您想要精确的 dp 值,就像在 xml 中一样,只需将其除以 DisplayMetrics 密度

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

dp现在是48

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

Resource类还有一个方法getDimensionPixelSize()我认为它会满足您的需求。

对于那些只需要在资源中保存一些int值的人,您可以执行以下操作。

整数.xml

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

代码

int defaultValue = getResources().getInteger(R.integer.default_value);

您可以使用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

您也可以在 xml 文件中写入整数..
你看过[这个] http://developer.android.com/guide/topics/resources/more-resources.html#Integer吗? 用于 。

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

这是一个更好的解决方案,不涉及从 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);
    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)

定义 UI 布局时应使用的虚拟像素单位,以与密度无关的方式表示布局尺寸或位置。 与密度无关的像素相当于 160 dpi 屏幕上的一个物理像素,这是系统为“中等”密度屏幕假定的基线密度。 在运行时,系统会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. 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. 在定义应用程序的 UI 时,您应该始终使用 dp 单位,以确保您的 UI 在不同密度的屏幕上正确显示。

我认为根据分辨率更改值很好,但如果你不想这样做,请以 px 为单位......

参考这个链接

按照这个

dp

与密度无关的像素 - 基于屏幕物理密度的抽象单位。 这些单位是相对于 160 dpi(每英寸点数)的屏幕而言的,在该屏幕上 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 单位)是一种简单的解决方案,可以使布局中的视图尺寸针对不同的屏幕密度正确调整大小。 换句话说,它为不同设备上 UI 元素的真实尺寸提供了一致性。

像素

像素 - 对应于屏幕上的实际像素。 不推荐使用此度量单位,因为实际表示可能因设备而异; 每个设备每英寸的像素数可能不同,并且屏幕上可用的总像素数可能更多或更少。

如果您只想动态更改字体大小,那么您可以:

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

作为@achie 的回答,您可以像这样从dimens.xml 获取dp:

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
     */

资源维度值乘以相应的

为此,我在 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()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM