如何将 Kotlin 内联类与 Android 数据绑定集成?

Posted

技术标签:

【中文标题】如何将 Kotlin 内联类与 Android 数据绑定集成?【英文标题】:How to integrate Kotlin inline class with Android data binding? 【发布时间】:2019-06-05 23:42:28 【问题描述】:

Kotlin 引入了inline class,它是强类型类型别名。这在与数据库一起使用时很有用。例如,

inline class Age(val value: Int)
inline class Height(val value: Int)

当它们写入数据库时​​,它们会被编译为 Int,但 Kotlin 可以防止您不小心将 Height 放入 Age 字段中。如果您直接使用类型别名或Int,则可能使用类型别名但内联类会产生编译时错误。

但是,这些也会导致 android 数据绑定出现问题。当我尝试将String 内联类绑定到String 属性时,我得到data binding error

虽然可以编写一些类型的适配器来绕过这一点,但它破坏了使用内联类的目的,并且不适合为所有内联类创建适配器。

我想问有没有什么优雅的方法可以解决这个问题?

【问题讨论】:

如果你把你的内联类作为数据绑定布局中的变量,还是有问题吗? @JeelVankhede 这不起作用。如果我有inline class Name(val value : String) 并将MutableLiveData<Name>() 绑定到EditText.text,则会引发编译错误。但我可以绑定MutableLiveData<String>()。即使您直接绑定内联类,它仍然会失败。 包裹在ObservableFields里面怎么样?这是 Kotlin 本身的新功能,所以我认为可能需要时间来适应 Android 环境。 @JeelVankhede 如果您重载setValue(String)postValue(String)getValue(String),它应该与MutableLiveData 一起工作,但有没有一种方法可以一劳永逸地编写,即为所有 String 内联类只写一次。 【参考方案1】:

您需要了解的第一件事是内联类不仅仅是原始类型的包装器。它们不仅仅是类型别名。

现在来看你的例子,即使DataBinding 知道如果你将任何MutableLiveData<T> 实例放在xml 中,它将采用该特定变量的值(类似于mutableLiveData.value)。但如果你输入MutablLiveData<Age>mutableLiveData.value 将始终是 Age 类型,而不是 Int 类型。

请注意,inline class 创建了一个全新的类型,而不仅仅是类型别名。

我相信您在数据绑定中需要一个方法,该方法返回内联类对象中包含的值。

【讨论】:

以上是关于如何将 Kotlin 内联类与 Android 数据绑定集成?的主要内容,如果未能解决你的问题,请参考以下文章

将 Kotlin 内联类作为实体字段的房间数据库

如何在多平台 Android 模块中配置 Kotlin jvmTarget?

Kotlin 中的 Parcelize 值(内联)类

Kotlin快速入门:基础语法类与继承集合

Kotlin快速入门:基础语法类与继承集合

Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )