资源未找到异常:资源ID无效。为什么?

15

我正在尝试将一个浮点数添加到我的 dimens.xml 文件中。

我正在阅读 以下SO答案。当我尝试这个解决方案时,我遇到了评论中描述的异常。我正在努力弄清楚为什么会抛出该异常。

为了完整起见,这是XML:

<item name="zoom_level" format="float" type="dimen">15.0</item>

这是导致程序崩溃的代码:

final float zoom = this.getResources().getDimension(R.dimen.zoom_level);

我进入了Android源代码,并且这里是getDimension方法的定义:

public float getDimension(int id) throws NotFoundException {
    synchronized (mTmpValue) {
        TypedValue value = mTmpValue;
        getValue(id, value, true);
        if (value.type == TypedValue.TYPE_DIMENSION) {
            return TypedValue.complexToDimension(value.data, mMetrics);
        }
        throw new NotFoundException(
                "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
                + Integer.toHexString(value.type) + " is not valid");
    }
}

出于某种原因,value.type != TypedValue.TYPE_DIMENSION。我的Android源代码还没有完全设置好,所以我无法轻松地在其中添加一个Log.w("YARIAN", "value type is " + value.type)'语句。

然后我进入了getValue,调用链似乎是:

Resources.getValue -> AssetManager.getResourceValue -> AssetManager.loadResourceValue

loadResourceValue是一个本地方法,这就是我的挖掘结束的地方。

有人知道理解正在发生什么的最佳方法吗?


我还注意到Resources拥有TypedValue.TYPE_FLOATTypedValue.TYPE_DIMENSION。但在XML中,我无法编写type="float"

评论中描述的解决方法是使用type=string,然后使用Float.parse来获取浮点数。这是必要的吗?为什么?

4个回答

23
我知道回答有点晚,但你应该使用TypedValue#getFloat()而不是像你建议的那样将字符串解析为浮点数。
XML:
    <item name="float_resource" format="float" type="raw">5.0</item>

Java:

TypedValue out = new TypedValue();
context.getResources().getValue(R.raw.float_resource, out, true);
float floatResource = out.getFloat();

如果您希望的话,可以将fractionrawstring作为type,这只对R中的资源类有对应关系。


那么这个 XML 应该放在哪里呢?是应该放在 res/raw 中的 dimen.xml 吗? - G_V
@G_V 是的,我也这么认为 - 不过我认为这并不重要,因为所有内容都会被 R 捕捉到,对吧? - Rich
你知道我为什么要这样做吗?默认类型是dimension,所以当我使用format="float"时,我会出错吗?还是说这是我应该始终使用的东西?提前感谢。 - user2424380

4
现在有两个获取浮点数的方法:Resources.getFloat(从API 29开始)和ResourcesCompat.getFloat
val zoomLevel: Float = ResourcesCompat.getFloat(resources, R.dimen.zoom_level)

您可以将问题中的 zoom_level XML 保留不变。

3

我也遇到了这个问题,虽然错误信息不太有用,但我意识到我的问题是我在资源文件中只放了一个浮点值,并没有指定度量单位。例如将15.0转换为15.0dp将避免这个问题,并允许您仍然使用常规的尺寸资源。


这仅适用于您的浮点数实际上是空格的情况。但在我的情况下,我有一个 downPopLevel,它是一个介于0和1之间的值,用于设置视图的alpha。在这种情况下,这个解决方案是不正确的... - Jeehut

1
由Rich回答创建的Kotlin扩展函数:
fun Resources.getFloatValue(@DimenRes floatRes:Int):Float{
    val out = TypedValue()
    getValue(floatRes, out, true)
    return out.float
}

使用方法:

resources.getFloatValue(R.dimen.my_float)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接