studio databindingutil databinding kotlin android-databinding

databindingutil - databinding kotlin android studio



Enlace de datos de atributos personalizados de Kotlin (6)

Estoy tratando de establecer un atributo personalizado usando la Biblioteca de enlace de datos de Android en mi proyecto Kotlin de esta manera:

Diseño

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

Código

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

El error de tiempo de ejecución que obtengo es:

Un BindingAdapter in in no es estático y requiere un objeto para usar, recuperado del DataBindingComponent. Si no usa un método de inflación que toma un DataBindingComponent, use DataBindingUtil.setDefaultComponent o haga que todos los métodos BindingAdapter sean estáticos.

¿Algún indicador para resolverlo?

Esto sucede solo para atributos personalizados. El resto de los enlaces de datos funcionan bien


Agregar @JvmStatic antes de @BindingAdapter("imageUrl") solucionó mi problema.

Por ej .:

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


Esto funciono para mi

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

en xml así:

imageUrl="@{file.thumbnailLink}"


Intente cambiar el orden de las anotaciones. Parece solucionar el problema:

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

El problema es que el compilador getCompanion().loadImage usa getCompanion().loadImage contrario * .
Puede verificar esto en el com.your.package.databinding.*Binding generado com.your.package.databinding.*Binding Clase de com.your.package.databinding.*Binding

* Después de jugar un poco, noté que esto no tiene nada que ver con el orden de las anotaciones, pero parece ser aleatorio. Parece cambiar cada vez que presiono "reconstruir". Puede ser un error en kapt o en el compilador de Kotlin


La función (loadImage) necesita poner un objeto (Singleton en java) que no esté en clase y establecer @JvmStatic antes de @BindingAdapter("imageUrl") así:

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


O usando la extensión:

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

Ahora puede usar esta función en cualquier otro lugar


Simplemente mantenga la función en el nivel superior, no se necesita ninguna clase u objeto complementario, funcionará ya que las funciones de nivel superior en Kotlin se traducen a funciones miembro estáticas de la clase nombrada como FileNameKt menos que sea anulado por @file:JvmName anotación @file:JvmName

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

Una opción más es anotar la función de extensión como @BindingAdapter , funcionará ya que en bytecode la firma coincidirá exactamente con la firma esperada por DataBindings (el método generado todavía aceptará un objeto de la clase extendida como primer argumento), la función debe permanecer en el nivel superior también

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