ChatGPT解决这个技术问题 Extra ChatGPT

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

我想按原样加载值。我有两个 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”结尾的字符串......

我想知道这是否是 Android 中的错误,因为 Resources 有方法 getDimensionPixelSize(int id) 准确地指出它以像素返回,所以 getDimension(int id) 应该以 dp(依赖独立单元)返回,这将可以使用,例如 View {3 }

A
Alireza Noorali

在我的 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


我认为这里的文档特别不清楚。 “单位转换基于与资源关联的当前 DisplayMetrics。”当他们只想说他们转换为像素时。
如果您本质上要放弃显示指标乘数,那么您也可以只以 px 为单位定义您的维度。 48px。 getDimension(R.dimen.test) 将返回 48。
@Trilarion 不过,它们不会简单地转换为像素。他们说 dp 将给出相对于用于检索它的资源对象的比例的缩放像素值。一旦您进入各种获取资源的方式,这将更加相关。为简单起见,您可以将其视为相对于屏幕比例。还有 sp 或相对于系统文本大小的像素,以及 px 或直接像素。每个都是不同的,有不同的目的。
如果你想从 dimens.xml 中获取 sp 值,那么你需要 int sp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().scaledDensity)
J
Jug6ernaut
Context.getResources().getDimension(int id);

O
Ovidiu Latcu

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


这是错误的!如果您可以参考它明确指出 Returns Resource dimension value multiplied by the appropriate metric and truncated to integer pixels. 的文档,指标转换也会发生在 getDimensionPixelSize()
这是错误的。指标转换也使用此方法进行。
S
Suragch

对于那些只需要在资源中保存一些 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);

谢谢你,这是我正在寻找的更多东西,即使可能不是为了其他人,但这个提供的解决方案实际上让我对我的代码的其他领域有了一些了解
E
Eric Aya

您可以使用 getDimensionPixelOffset() 代替 getDimension,因此您不必强制转换为 int。

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

G
Gibolt

使用 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


A
AndroidLad

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

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

N
Nico

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

D
Dheeresh Singh
    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 屏幕上的一个物理像素,这是系统为“中等”密度屏幕假定的基线密度。在运行时,系统会根据需要透明地处理 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.在定义应用程序的 UI 时,您应该始终使用 dp 单位,以确保您的 UI 在不同密度的屏幕上正确显示。

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

参考这个link

按照这个

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 元素的真实尺寸提供了一致性。

像素

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


S
Seven

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

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

资源维度值乘以相应的


D
Dživo Jelić

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

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅