76 votes

Kotlin attribut personnalisé databinding

Je suis en train de définir l'attribut personnalisé à l'aide de l' Android de liaison de données de la Bibliothèque dans mon Kotlin projet 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)}
    }       

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

Un BindingAdapter en est pas statique et nécessite un objet pour l'utiliser, extrait de la DataBindingComponent. Si vous n'utilisez pas une inflation méthode de prendre un DataBindingComponent, utilisez DataBindingUtil.setDefaultComponent ou les faire toutes BindingAdapter méthodes statiques.

Tous les pointeurs à le résoudre?

Cela se produit uniquement pour les attributs personnalisés. Le reste de la databindings beau travail

124voto

Stepango Points 2812

Il suffit de garder la fonction de haut niveau, pas de classe ou d'un compagnon objet de besoin, il va travailler depuis les fonctions de niveau supérieur dans Kotlin traduit de fonctions membres statiques de la Classe nommée FileNameKt moins remplacées par d' @file:JvmName d'annotation

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

Une autre option est d'annoter l'Extension de la Fonction en tant que @BindingAdapter, il va travailler depuis dans le bytecode à la signature correspondent exactement à celles signature prévue par DataBindings(généré méthode accepte un objet de la classe étendue que le premier argument), la fonction doit rester haut niveau ainsi

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

43voto

Lovis Points 3935

Essayez de changer l'ordre des annotations. Il semble que pour 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 le générés com.your.package.databinding.*Binding classe

* 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 l'ai frappé "reconstruire". Il peut-être un bug en kapt ou dans le kotlin compilateur

14voto

Ajouter @JvmStatic avant @BindingAdapter("imageUrl") résolu 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 } }

3voto

Yazazzello Points 3299

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

2voto

Fidan Bacaj Points 72

La fonction (loadImage) doit mettre en objet (Singleton en java) pas dans la classe et définir @JvmStatic avant @BindingAdapter("imageUrl") comme ceci:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X