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