Kotlin 自定义属性数据绑定

我正在尝试使用 < a href = “ https://developer.Android.com/subject/Library/data-binding/index.html”rel = “ noReferrer”> Android DataBinding Library 来设置自定义属性 在我的科特林项目中,就像这样:

布局

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


    



    

我得到的运行时错误是:

< package 中的 BindingAdapter。水管。同伴 > 不是静态的,需要从 DataBindingComponent 检索到一个要使用的对象。如果不使用带有 DataBindingComponent 的膨胀方法,请使用 DataBindingUtil.setDefaultComponent 或使所有 BindingAdapter 方法成为静态的。

有什么解决办法吗?

这只发生在自定义属性上,其余的数据绑定可以正常工作

23293 次浏览

试着改变注释的顺序,似乎可以解决这个问题:

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

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

玩了一会儿之后,我注意到这和注释的顺序没有关系,但是看起来是随机的。每当我点击“重建”,它似乎都会改变。它可能是 kapt或 kotlin 编译器中的错误

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

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

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

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

还有一种选择是将 BindingAdapter与扩展属性组合在一起,如下所示:

@set:BindingAdapter("visible")
var View.visible
get() = visibility == VISIBLE
set(value) {
visibility = if (value) VISIBLE else GONE
}

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

例如:

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

或使用扩展名:

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

现在您可以在其他任何地方使用这个函数

函数(loadImage)需要在类中放入 object (Java 中的 Singleton) ,并在 @BindingAdapter("imageUrl")之前设置 @JvmStatic,如下所示:

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

这招对我很管用

object ImageUtils {


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

如下所示:

imageUrl="@{file.thumbnailLink}"

这是为我工作。请在下面找到它. 。

加上梯度:

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 = “@{ animes.imageUrl }

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