【问题标题】:Can not use BindingAdapter in Kotlin无法在 Kotlin 中使用 BindingAdapter
【发布时间】:2018-08-16 11:10:21
【问题描述】:

我曾经创建 DataBindingAdapter 用于在数据绑定中创建自定义 xml 属性。

object DataBindingAdapter {
    @BindingAdapter("android:src")
    fun setImageByRes(imageView: ImageView, @DrawableRes resId: Int) {
        imageView.setImageResource(resId)
    }
}

运行良好 在 Java 中但不起作用 在 kotlin 中

据我了解,kotlin 中的对象类似于 Java 的静态方法。但它不适用于数据绑定。

java.lang.IllegalStateException:FragmentBottomBarBinding 类中必需的 DataBindingComponent 为空。中的 BindingAdapter acr.browser.lightning.utils.DataBindingAdapter 不是静态的并且 需要使用从 DataBindingComponent 检索的对象。如果 您不使用采用 DataBindingComponent 的通胀方法,请使用 DataBindingUtil.setDefaultComponent 或制作所有 BindingAdapter 方法 静态的。

【问题讨论】:

  • 你试过@JvmStatic注解setImageByRes
  • 如果您遇到互操作问题(Java 调用 Kotlin 代码),一个好的方法是将生成的字节码反编译为 Java 并查看结果如何。这通常可以立即明确接口不匹配的位置。
  • @Moinkhan JvmStatic 成功了。
  • 你忘了@JvmStatic
  • 因为你没有回答,所以我做了你的工作。你现在可以回答了。我会正确地标记它,你应得的。

标签: android kotlin android-databinding


【解决方案1】:

只需在 setImageByRes 方法上添加 @Jvmstatic 注释即可。

object DataBindingAdapter {
    @BindingAdapter("android:src")
    @JvmStatic
    fun setImageByRes(imageView: ImageView, @DrawableRes resId: Int) {
        imageView.setImageResource(resId)
    }
}

根据@Jvmstaticdoc

如果它是一个函数,则指定需要从此元素生成一个额外的静态方法。如果此元素是属性,则应生成额外的静态 getter/setter 方法。

简而言之,在一个地方声明并从 JVM 的多种语言中使用的方法。如果你从 Java 调用一个方法,那么你应该将它声明为 @JvmStatic,因为在一个地方添加 @JvmStatic 注释将允许你在多个地方省略多个 .Companion 引用。

【讨论】:

  • 如果你为新人添加一点关于 JvmStatic 的信息,那就太好了。
  • 嗨 @Moinkhan 如何将此 DataBindingAdapter 与回收器视图或适配器链接?
【解决方案2】:

没有。 kotlin 中的对象与单例相同。我认为你不需要把它放在对象中。只需创建新文件,比如说BindingAdapters.kt,您不需要编写任何类或对象关键字。

它应该看起来像这样。没有其他的。如果您需要更多功能,只需将其添加到此功能下方即可。同样不需要类关键字或括号。它将是全局函数。也许您还应该使用ContextCompat 来正确获取resource 以及来自imageView 的上下文。我宁愿将它命名为不同于 android:src。 imageResBinder 呢

@BindingAdapter("imageResBinder")
fun setImageByRes(imageView: ImageView, @DrawableRes resId: Int) {
    imageView.setImageResource(resId)
}

然后在您的.xml 文件中

<android.support.v7.widget.AppCompatImageView
    style="@style/Image.SomeImageStyle"
    app:imageResBinder="@{viewModel.getImageRes()}" />

【讨论】:

  • 如果需要,如何从另一个 kotlin 调用此函数?
  • 你不能。您唯一能做的就是从不同的 .xml 文件中调用它,因为它的全局方法仅用于数据绑定。所以你不能说在片段 onViewCreated() 中调用它。当然,您可以创建一个静态类来加载资源,但我认为如果您使用数据绑定,您不应该这样做。你也可以把这个 bindingAdapter 放到某个模型类中:stackoverflow.com/questions/40845767/…
  • 那么我会更喜欢@JvmStatic,因为可能有一些通用函数也可以用于从另一个活动中调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多