[JAVA] Trébucher avec Android DataBinding + Kotlin (plus BindingAdapter)

introduction

En utilisant DataBinding, j'écrirai sur le point d'achoppement et comment le résoudre. (La moitié est un mémorandum) Il existe de nombreux conseils lors de la création d'un setter personnalisé (annotation BindingAdapter).

Erreur BindingAdapter dans Kotlin

Quand j'ai créé un setter personnalisé en Java, je pouvais l'écrire comme ça.

@BindingAdapter("imageUrl")
public static void loadImage(ImageView view, String url) {
   // do something
}

Tout d'abord, j'ai écrit un setter personnalisé à Kotlin:

class ImageViewBindingAdapter {
    companion object {
        @BindingAdapter("imageUrl")
        @JvmStatic
        fun loadImage(view: ImageView, imageUrl: String) {
            // do something
        }
    }
}

DataBindingAttribute.Companion is not static and requires an object to use, retrieved from the DataBindingComponent.

La méthode statique utilisant «objet compagnon» entraînera l'erreur ci-dessus. Vous pouvez écrire un setter personnalisé par la méthode suivante.

object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    @JvmStatic
    fun loadImage(view: ImageView, imageUrl: String) {
        // do something
    }
}

Vous pouvez également utiliser les fonctions d'extension de Kotlin.

object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String) {
        // do something
    }
}

XML est le même pour Java et Kotlin.

<ImageView 
    app:imageUrl="@{viewModel.imageUrl}" />

Spécifiez plusieurs paramètres pour le setter personnalisé dans Kotlin

Avec Java, je pourrais écrire comme ça.

@BindingAdapter({"imageUrl", "error"})
public static void loadImage(ImageView view, String url, Drawable error) {
   // do something
}

C'est le cas de Kotlin.

object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl", "error")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String, error: Drawable) {
        // do something
    }
}

En XML, écrivez:

<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:error="@{@drawable/errorImage}" />

Comme indiqué ci-dessous, cela ne fonctionne pas bien si seuls certains paramètres sont spécifiés.

<ImageView 
    app:imageUrl="@{viewModel.imageUrl}" />

Cela est dû au fait que l'attribut requireAll du BindingAdapter est par défaut true. Dans ce cas, il ne sera appelé que si tous les paramètres sont spécifiés. Pour le rendre appelé par certains paramètres, réécrivez BindingAdapter comme suit.

@BindingAdapter("imageUrl", "error", requireAll = false)

Je veux passer Int, Boolean à BindingAdapter

Je voulais définir Int sur BindingAdapter, j'ai donc écrit ce qui suit, mais cela n'a pas fonctionné.

object ImageViewBindingAdapter {
    @BindingAdapter("imageUrl", "position")
    @JvmStatic
    fun ImageView.loadImage(imageUrl: String, position: Int) {
        // do something
    }
}
<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:position="1" />

La cause réside dans la façon dont il est écrit en XML, et cela fonctionne si vous le modifiez comme suit.

<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:position="@{1}" />

Si vous voulez passer un booléen, écrivez:

<ImageView 
    app:imageUrl="@{viewModel.imageUrl}"
    app:dispflag="@{true}" />

Je ne sais pas pourquoi je dois écrire ceci, alors faites-le moi savoir si quelqu'un le sait.

Je souhaite transmettre l'ID de ressource à BindingAdapter

Vous pouvez importer la classe R comme suit.

<data>
    <import type="com.sample.R"/>
    <variable 
        name="viewModel"
        type="com.sample.TestViewModel" />
</data>
<ImageView 
    app:src="@{viewModel.resourceId ?: R.drawable.error}" />

Je souhaite gérer des événements autres qu'android: onClick

Tout d'abord, j'ai vérifié s'il y avait un adaptateur fourni en standard. https://android.googlesource.com/platform/frameworks/data-binding/+/master/extensions/baseAdapters/src/main/java/android/databinding/adapters

Par exemple, si vous souhaitez utiliser ʻandroid: onTextChanged de ʻEditTextView, [TextViewBindingAdapter.java](https://android.googlesource.com/platform/frameworks/data-binding/+/master/extensions/baseAdapters/src/ (main / java / android / databinding / adapters / TextViewBindingAdapter.java) a déjà un BindingAdapter afin que vous puissiez l'utiliser.

Il existe également une description de BindingMethod ici, vous n'aurez donc peut-être pas besoin de vous soucier de préparer une méthode BindingMethod comme set ** Listener.

Je veux utiliser le contexte comme argument

Lorsque je voulais utiliser une méthode qui a Context comme argument dans DataBinding, je me suis référé à l'article suivant. Passez-le simplement en tant que «contexte» et cela fonctionnera.

Gérer une méthode qui passe le contexte en tant qu'argument dans DataBinding

Recommended Posts

Trébucher avec Android DataBinding + Kotlin (plus BindingAdapter)
J'ai créé une application de calculatrice sur Android
J'ai essayé d'utiliser "nifty cloud mobile backend" et l'authentification "Firebase" sur Kotlin + Android
Je suis tombé sur la version Java dans Android Studio, je vais donc le résumer
[Android Studio] Je souhaite utiliser une bibliothèque Maven sur Android
J'ai créé une bibliothèque pour afficher des tutoriels sur Android.
Ce sur quoi je suis tombé lors de l'installation de Ruby sur Ubuntu
Je souhaite simplifier la sortie du journal sur Android