Невозможно использовать значение с плавающей запятой из файла измерения при привязке данных - PullRequest
1 голос
/ 11 февраля 2020

Android Studio 3.6

в моих строках. xml

<string name="discount_bonuses_and_ration_lei_placeholder">%1$d B x %2$.2f Lei</string>

в моих xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View" />


        <variable
            name="item"
            type="com.myprroject.api.model.Invoice" />
    </data>


    <TextView
        android:id="@+id/discountBonusesTextView"
        style="@style/order_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@{@string/discount_bonuses_and_ration_lei_placeholder(item.bonuse, 0.1)}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="@+id/discountLabelTextView"
        app:layout_constraintTop_toBottomOf="@+id/discountLabelTextView" />

</layout>

все работает нормально. Хорошо.

Теперь я хочу заменить жестко закодированное значение 0.1 на значение из файла dimen. Итак, в values/dimen.xml

<item name="ratio_bonus" format="float" type="dimen">0.1</item>

И я пишу метод, который получает значение с плавающей запятой из файла измерения.

  public static float getFloatValueFromDimen(Context context, int dimenKey) {
        TypedValue typedValue = new TypedValue();
        context.getResources().getValue(dimenKey, typedValue, true);
        float dimenfloatValue = typedValue.getFloat();
        return dimenfloatValue;
    }

Теперь я хочу использовать этот метод в xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View" />

        <import type="com.myproject.util..AndroidUtil" />


        <variable
            name="item"
            type="com.myprroject.api.model.Invoice" />
    </data>


    <TextView
        android:id="@+id/discountBonusesTextView"
        style="@style/order_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@{@string/discount_bonuses_and_ration_lei_placeholder(item.bonuse, AndroidUtil.getFloatValueFromDimen(context, @dimen/ratio_bonus))}"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="@+id/discountLabelTextView"
        app:layout_constraintTop_toBottomOf="@+id/discountLabelTextView" />
</layout>

Но теперь я получаю ошибку компиляции

import com.myproject.databinding.ConfirmationActivityBindingImpl;
                                                  ^
  symbol:   class ConfirmationActivityBindingImpl
location: package com.myprojectt.databinding

ConfirmationActivity - это действие, которое использует мой xml с привязкой данных

1 Ответ

2 голосов
/ 11 февраля 2020

Проблема - 1: Вы не объявили context в своем xml, следовательно, привязка данных показывает ошибку и не может создать ConfirmationActivityBindingImpl

Решение : Создать имя переменной context с типом android.content.Context

<variable
    name="context"
    type="android.content.Context" />

И Инициализировать context из вашего activity.

Теперь это успешно создайте ConfirmationActivityBindingImpl и это будет выглядеть так:

....

androidx.databinding.adapters.TextViewBindingAdapter
        .setText(this.discountBonusesTextView, 
                discountBonusesTextView.getResources()
                        .getString(R.string.discount_bonuses_and_ration_lei_placeholder, 100, 
                                discountBonusesTextView.getResources().getDimension(R.dimen.ratio_bonus)));

....

Задача - 2: Тогда это вызывает Ресурсы $ NotFoundException из-за float измерения типа.

android .content.res.Resources $ NotFoundException: идентификатор ресурса # 0x7f060163 тип # 0x4 недопустим в android .content.res. Resources.getDimension

Если мы посмотрим внутрь getDimension, есть проверка типов и throw исключение, если нет TYPE_DIMENSION

if (value.type == TypedValue.TYPE_DIMENSION) {
    return TypedValue.complexToDimension(value.data, impl.getDisplayMetrics());
}

throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
                + " type #0x" + Integer.toHexString(value.type) + " is not valid");

Решение: Мы должны передать Идентификатор ресурса вместо Значение ресурса . Для этого

  • import R. java внутри вашего xml
<import type="com.myproject.databinding.R"/>
  • И затем передать ресурс id вроде R.dimen.ratio_bonus
AndroidUtil.getFloatValueFromDimen(context, R.dimen.ratio_bonus)

Теперь он будет обрабатываться вашим getFloatValueFromDimen вместо системного getDimension и все работает нормально.

...