使用自定义转换器进行双向数据绑定

时间:2019-04-05 13:31:39

标签: android android-databinding android-architecture-components android-viewmodel

我想将数据绑定与视图模型结合使用,如here

所述

所以这是节选:

布局:

    <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)
    }
}

viewmodel:

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 ****

我正在使用最新的数据绑定alpha,所以我想知道lib中是否可能存在错误。

任何帮助!

---更新

如果我这样编写转换器,则它将编译,但是与文档不符。知道为什么吗?

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)
    }
}

1 个答案:

答案 0 :(得分:0)

有点旧的线程,但是我也一直在努力进行2向数据绑定,所以对于任何需要解决此问题的人来说,问题是Unlundo按照其文档记录了转换器的方式,其中有一个View,旧的和新的价值。但是,有关此文档的内容不是很清楚。

类型转换器中的参数也必须存在于布局文件中。对于布局中的原始绑定android:text="@={Converter.dateToString(viewmodel.birthday)}",只有一个参数-viewmodel.birthday,我们假设它是一个日期。因此,我们的类型转换器和逆转换器仅获得1个参数。

如果您将同一个转换器重新用于多个绑定,并且希望能够看到用户更改了哪个视图,则可以通过在布局中使用其ID将视图作为参数传递。这将通过生日,以及用户正在编辑的视图:

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

这还意味着您的类型转换器和逆转换器在EditText的开头都需要一个附加参数。该库似乎确实足够聪明,可以正确地查看视图,并且至少不仅仅给您一个View作为参数。

此外,如果您仅在朝字符串方向发射时在转换器中苦苦挣扎,请确保您确实设置了绑定变量。如果布局要绑定的变量是null,它将把默认值转换为显示,但不能将任何东西绑定回