使用自定义转换器实现双向数据绑定

5

我希望使用数据绑定和视图模型,如此这里所解释的。

因此,以下是摘录:

布局:

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

我正在使用最新的数据绑定 alpha 版本,所以我想知道库中是否可能存在 bug。
感谢任何帮助!
--- 更新
如果我像这样编写转换器,则可以编译,但这与文档不符。有什么想法吗?
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)
    }
}

你能否在你的 dateToString 转换方法上尝试使用 @JvmStatic 注解?也许数据绑定编译器无法找到静态方法 dateToString - Jeel Vankhede
@JeelVankhede 我刚试了一下,但没有变化。 - unludo
如果您在包com.unludo.interview.persons.edit中有此对象类,请尝试在对象文件开头添加此注释:@file:JvmName("Converter") - Jeel Vankhede
@JeelVankhede 仍然是一样的。 - unludo
@JeelVankhede 我也尝试过那样做,但结果还是一样。我找到了一种方法,但它不应该像这样工作。 - unludo
1个回答

1

这是一个有点老的帖子,但我也一直在苦苦挣扎双向数据绑定,所以对于任何需要此答案的人来说,问题在于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,它将将默认值转换为显示,但无法绑定任何内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接