Liaison de données d'attribut personnalisé Kotlin

J'essaie de définir un attribut personnalisé en utilisant la bibliothèque de liaison de données Android dans mon projet Kotlin comme ceci:

Mise en page

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

Code

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

L'erreur d'exécution que je reçois est:

Un BindingAdapter in in n'est pas statique et nécessite un objet à utiliser, récupéré à partir du DataBindingComponent. Si vous n'utilisez pas une méthode d'inflation prenant un DataBindingComponent, utilisez DataBindingUtil.setDefaultComponent ou make all bindingadapter methods statique.

Des pointeurs pour le résoudre?

Cela se produit uniquement pour les attributs personnalisés. Le reste des bases de données fonctionne bien

33
demandé sur PLNech 2016-10-17 14:53:54

4 réponses

Il suffit de garder la fonction au niveau supérieur, Pas de classe ou d'objet compagnon nécessaire, cela fonctionnera puisque les fonctions de niveau supérieur dans Kotlin sont traduites en fonctions membres statiques de la classe nommée FileNameKt sauf si elles sont remplacées par @file:JvmName annotation

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

Une autre option consiste à annoter la fonction D'Extension comme @BindingAdapter, cela fonctionnera car dans bytecode la signature correspondra exactement à la signature attendue par DataBindings(la méthode générée acceptera toujours un objet de la classe étendue comme premier argument), le la fonction doit également rester au niveau supérieur

@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }
57
répondu Stepango 2018-03-24 10:27:33

Essayez de changer l'ordre des annotations. Il semble résoudre le problème:

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

Le problème est que Le databindng compilateur utilise getCompanion().loadImage autrement*.
Vous pouvez le vérifier dans la classe com.your.package.databinding.*Binding {[5 générée]}

* Après avoir joué un peu, j'ai remarqué que cela n'a rien à voir avec l'ordre des annotations, mais semble être aléatoire. Il semble changer chaque fois que je frappe "reconstruire". Il peut s'agir d'un bogue dans kapt ou dans le compilateur kotlin

18
répondu Lovis 2016-10-17 14:04:40

Ajout de @JvmStatic avant @BindingAdapter("imageUrl") corrigé mon problème.

Pour ex:

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

2
répondu tieorange 2018-01-04 18:12:36

Ou en utilisant l'extension:

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

Maintenant, vous pouvez utiliser cette fonction n'importe où ailleurs

1
répondu Yazazzello 2018-03-21 20:22:27