Kotlin自定义属性数据绑定

时间:2016-10-17 11:53:54

标签: kotlin android-databinding

我正在尝试使用Android DataBinding Library设置自定义属性 在我的Kotlin项目中这样:

布局

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

代码

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

我得到的运行时错误是:

  

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

任何解决它的指针?

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

7 个答案:

答案 0 :(得分:83)

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

@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }

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

@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }

答案 1 :(得分:24)

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

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

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

中验证这一点

* 在玩了一下之后,我注意到这与注释的顺序无关,但似乎是随机的。每当我点击&#34;重建&#34;它似乎都会改变。它可能是kapt或kotlin编译器

中的错误

答案 2 :(得分:5)

@JvmStatic修复我的问题之前添加@BindingAdapter("imageUrl")

例如:

object BindingAdapters { @BindingAdapter("android:visibility") @JvmStatic fun setVisibility(view: View, visible: Boolean) { view.visibility = if (visible) View.VISIBLE else View.GONE } }

答案 3 :(得分:2)

或使用扩展程序:

@BindingAdapter("imageUrl")
fun ImageView.setImageUrl(url: String?) {
    Picasso.with(context).load(url).into(this)
}

现在你可以在其他地方使用这个功能

答案 4 :(得分:1)

函数(loadImage)需要放入对象(java中的Singleton)而不是类中,并在@JvmStatic之前设置@BindingAdapter("imageUrl"),像这样:

<ImageView
android:id="@+id/imgView”
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
imageUrl="@{segment.url}"/>

   @JvmStatic
   @BindingAdapter("bind:imageUrl")
   fun ImageView.loadImage( url:String) {
Picasso.with(this.context).load(url).error(R.drawable.error).into(this)
}

答案 5 :(得分:1)

这对我有用。请在下面找到它。

添加gradle:

apply plugin: 'kotlin-kapt'

dependencies {
 kapt "com.android.databinding:compiler:3.1.4"
}

添加POJO:

companion object {
  @BindingAdapter("image")
    @JvmStatic
         fun loadImage(view: ImageView, imageUrl: String) {

             //am Using Glide
Glide.with(view.context).setDefaultRequestOptions(RequestOptions().circleCrop())
                 .load(imageUrl).into(view)
         }
     }

在布局中:

添加bind:image =“ @ {movies.imageUrl}

<ImageView 
  android:id="@+id/imageView"
  android:layout_width="100dp"
  android:layout_height="100dp"
  bind:image="@{movies.imageUrl}/>

答案 6 :(得分:0)

这对我有用

object ImageUtils {

        @JvmStatic @BindingAdapter("imageUrl")
        fun ImageView.loadImage(url: String?){
                GlideHelper.loadImage(url,this)
        }
}

在xml中是这样的:

imageUrl="@{file.thumbnailLink}"