Ресурсы $ NotFoundException: недопустимый идентификатор ресурса. Почему?

Я пытаюсь добавить в свой 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_FLOAT и TypedValue.TYPE_DIMENSION. Но в XML я не могу писать type="float".

Обход, описанный в комментариях, заключается в использовании type=string, а затем Float.parse для получения числа с плавающей запятой. Это необходимо? Почему или почему нет?


person yarian    schedule 27.03.2013    source источник


Ответы (4)


Я знаю, что это поздний ответ, но вам следует использовать TypedValue # getFloat () вместо синтаксического анализа String на float, как вы предложили.

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.

person Rich    schedule 10.06.2013
comment
Итак, куда должен идти этот XML? Размер xml в res / raw? - person G_V; 06.03.2016
comment
@G_V Да, я так думаю - хотя я не думаю, что это действительно имеет значение, поскольку R все равно все это забирает? - person Rich; 06.03.2016
comment
И ты знаешь, почему я должен идти этим путем? Тип по умолчанию - размер, поэтому, когда я использую format = float, я ошибаюсь? Или это то, что я всегда должен использовать? спасибо заранее - person user2424380; 27.02.2018

Я тоже столкнулся с этой проблемой, и, хотя сообщение об ошибке не слишком полезно, я понял, что моя проблема в том, что я помещал только значение с плавающей запятой в свой файл ресурсов и не указывал измерение. Например, переключение с 15.0 на 15.0dp позволит избежать проблемы и позволит вам по-прежнему использовать обычный ресурс измерения.

person gdawgrancid    schedule 12.04.2018
comment
Это работает, только если ваши числа с плавающей запятой на самом деле являются пробелами. Но в моем случае у меня есть downPopLevel, который представляет собой значение от 0 до 1 для установки альфы в представлениях. В таком случае это решение неверно ... - person Jeehut; 01.09.2020

Теперь есть Resources.getFloat (из API 29 ) и ResourcesCompat.getFloat:

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

Вы можете оставить свой zoom_level XML как есть в вопросе.

person Pavel Haluza    schedule 25.08.2020

Функция расширения Kotlin сделана из Rich answer:

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

Использование:

resources.getFloatValue(R.dimen.my_float)
person Jacek Pietras    schedule 05.05.2020