Двусторонняя привязка данных с пользовательским конвертером

Я хочу использовать привязку данных с моделью представления, как описано здесь

Итак, вот выдержки:

макет:

    <data class="FragmentEditPersonDataBinding">
    <import type="com.unludo.interview.persons.edit.Converter"/>

    <variable
        name="viewmodel"
        type="com.unludo.interview.persons.edit.PersonEditViewModel" />
   [...]
                 <EditText
                android:id="@+id/editBirthday"
                android:inputType="date"
                android:text="@={Converter.dateToString(viewmodel.birthday)}"

преобразователь:

object Converter {
    @InverseMethod("stringToDate")
    @JvmStatic
    fun dateToString(
            view: EditText, oldValue: String,
            value: Date
    ): String {
        val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE)

        return sdf.format(value)
    }

    @JvmStatic   
    fun stringToDate(
            view: EditText, oldValue: String,
            value: String
    ): Date {
        val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE)

        return sdf.parse(value)
    }
}

модель просмотра:

class PersonEditViewModel {
    var birthday: Date = GregorianCalendar(1993, 5, 19).time
    ...

Теперь я получаю эту ошибку при сборке:

e: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: 
    Found data binding errors.
****/ data binding error ****msg:cannot find method dateToString(java.util.Date) 
    in class com.unludo.interview.persons.edit.Converter 
[...]
 - 134:78 ****\ data binding error ****

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

Спасибо за любую помощь!

--- Обновить

Если я напишу конвертер так, то он компилируется, но это не соответствует документации. Есть идеи, почему?

object Converter {

    @InverseMethod("stringToDate")
    @JvmStatic
    fun dateToString(
            value: Date
    ): String {
        val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE)

        return sdf.format(value)
    }
    @JvmStatic
    fun stringToDate(
            value: String
    ): Date {
        val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE)

        return sdf.parse(value)
    }
}

comment
Можете ли вы попробовать аннотацию @JvmStatic в вашем методе конвертера dateToString? Возможно, компилятор привязки данных не может найти статический метод dateToString.   -  person Jeel Vankhede    schedule 05.04.2019
comment
@JeelVankhede Я только что попробовал, но без изменений   -  person unludo    schedule 05.04.2019
comment
Если у вас есть этот класс объекта в этом пакете com.unludo.interview.persons.edit, попробуйте эту аннотацию в начале вашего объектного файла @file:JvmName("Converter").   -  person Jeel Vankhede    schedule 05.04.2019
comment
@JeelVankhede Всё тот ​​же   -  person unludo    schedule 05.04.2019
comment
@JeelVankhede Я тоже пробовал, но все равно. Я нашел способ, но он не должен работать так.   -  person unludo    schedule 05.04.2019


Ответы (1)


Немного старая ветка, но я также боролся с двусторонней привязкой данных, поэтому для тех, кому нужен ответ на этот вопрос, проблема в том, что Unlundo сделал свой конвертер так, как задокументировано, где есть представление и старый, и новое значение. Однако документация для этого не очень ясна.

Аргументы ваших преобразователей типов также должны присутствовать в вашем файле макета. Для исходной привязки в макете, android:text="@={Converter.dateToString(viewmodel.birthday)}", есть только один аргумент — viewmodel.birthday, который, как мы предполагаем, является датой. Поэтому наш преобразователь типов и обратный преобразователь получают только 1 аргумент.

Если вы повторно используете один и тот же преобразователь для нескольких привязок и хотите видеть, какое представление изменил пользователь, вы можете передать представление в качестве аргумента, используя его идентификатор в макете. Это пройдет в день рождения и вид, который редактировал пользователь:

                <EditText
                android:id="@+id/editBirthday"
                android:inputType="date"
                android:text="@={Converter.dateToString(edtBirthday, viewmodel.birthday)}"

Это также будет означать, что ваш преобразователь типов и обратный преобразователь нуждаются в дополнительном аргументе в начале для EditText. Библиотека кажется достаточно умной, чтобы правильно определить тип представления, а не просто дать вам View в качестве аргумента, по крайней мере.

Кроме того, если вы боретесь с конвертером только в направлении строки, убедитесь, что вы действительно установили переменную привязки. Если переменная, с которой связывается макет, имеет значение null, она преобразует значения по умолчанию для отображения, но не сможет ничего связать обратно.

person Zalerinian    schedule 10.02.2020