14

我正在尝试在我的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_FLOATand TypedValue.TYPE_DIMENSION。但在 XML 中,我无法编写type="float".

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

4

4 回答 4

22

我知道这是一个迟到的答案,但你应该使用TypedValue#getFloat()而不是像你建议的那样将字符串解析为浮点数。

XML:

    <item name="float_resource" format="float" type="raw">5.0</item>

爪哇:

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

您可以放置fraction​​ ,raw或者string如果type您愿意,这仅对应于 中的资源类R

于 2013-06-10T15:31:41.477 回答
3

我也遇到了这个问题,虽然错误消息没有太大帮助,但我意识到我的问题是我在资源文件中只放了一个浮点值并且没有指定测量值。例如,将 15.0 切换到 15.0dp 可以避免该问题并允许您仍然使用常规维度资源。

于 2018-04-12T21:31:59.830 回答
2

现在有Resources.getFloat(来自 API 29)和ResourcesCompat.getFloat

val zoomLevel: Float = ResourcesCompat.getFloat(resources, R.dimen.zoom_level)

您可以将zoom_levelXML 保留在问题中。

于 2020-08-25T16:14:12.403 回答
1

由丰富的答案制成的 Kotlin 扩展功能:

fun Resources.getFloatValue(@DimenRes floatRes:Int):Float{
    val out = TypedValue()
    getValue(floatRes, out, true)
    return out.float
}

用法:

resources.getFloatValue(R.dimen.my_float)
于 2020-05-05T11:28:18.337 回答