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).
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}" />
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 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.
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}" />
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.
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