Kotlin自定义属性数据绑定

Aks*_*ata 57 kotlin android-databinding

我试图 在我的Kotlin项目中使用Android DataBinding库设置自定义属性,如下所示:

布局

<ImageView
    android:id="@+id/imgView”
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    app:imageUrl="@{segment.url}"/>
Run Code Online (Sandbox Code Playgroud)

  class Utils {
        companion object {
            @BindingAdapter("bind:imageUrl")
            @JvmStatic
            fun loadImage(view: ImageView, url:String) 
            {Picasso.with(view.context).load(url).error(R.drawable.error).into(view)}
    }       
Run Code Online (Sandbox Code Playgroud)

我得到的运行时错误是:

in中的BindingAdapter不是静态的,需要使用从DataBindingComponent检索的对象.如果不使用带有DataBindingComponent的通胀方法,请使用DataBindingUtil.setDefaultComponent或使所有BindingAdapter方法保持静态.

任何解决它的指针?

这仅适用于自定义属性.其余的数据绑定工作正常

Ste*_*ngo 96

只需将函数保持在顶层,不需要类或伴随对象,它将起作用,因为Kotlin中的顶级函数转换为名为Class的静态成员函数,FileNameKt除非被@file:JvmName注释覆盖

@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
Run Code Online (Sandbox Code Playgroud)

还有一个选项是注释扩展函数@BindingAdapter,它将起作用,因为在字节码签名中将完全匹配DataBindings期望的签名(生成的方法仍将接受扩展类的对象作为第一个参数),该函数应该保持最高级别

@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }
Run Code Online (Sandbox Code Playgroud)

  • 这个答案仍然给我错误.洛维斯的回答对我有用. (2认同)

Lov*_*vis 28

尝试切换注释的顺序.它似乎解决了这个问题:

class Utils {
    companion object {
        @JvmStatic @BindingAdapter("imageUrl")
        fun loadImage(view: ImageView, url:String) { ... } 
    }
} 
Run Code Online (Sandbox Code Playgroud)

问题是databindng编译器getCompanion().loadImage否则使用*.
您可以在生成的com.your.package.databinding.*Binding类中验证这一点

*玩了一下之后我注意到这与注释的顺序无关,但似乎是随机的.每当我点击"重建"时它似乎都会改变.它可能是kaptkotlin编译器中的错误

  • 我把一个kotlin bug报告起来了https://youtrack.jetbrains.com/issue/KT-14417 (4认同)
  • 绑定查找静态方法以及在随播对象中提供@JvmStatic可以解决问题 (3认同)

Анд*_*чук 6

解决@JvmStatic后添加@BindingAdapter("imageUrl")我的问题。

例如:

    @BindingAdapter("android:visibility")
    @JvmStatic
    fun setVisibility(view: View, visible: Boolean) {
        view.visibility = if (visible) View.VISIBLE else View.GONE
    }
}
Run Code Online (Sandbox Code Playgroud)