[JAVA] Stolpern Sie mit Android DataBinding + Kotlin (mehr BindingAdapter)

Einführung

Mit DataBinding schreibe ich über den Stolperpunkt und wie man ihn löst. (Die Hälfte ist ein Memorandum) Beim Erstellen eines benutzerdefinierten Setters (BindingAdapter-Annotation) gibt es viele Tipps.

BindingAdapter-Fehler in Kotlin

Wenn ich einen benutzerdefinierten Setter in Java erstellt habe, konnte ich ihn so schreiben.

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

Zuerst habe ich einen benutzerdefinierten Setter in Kotlin geschrieben:

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.

Die statische Methode mit dem Begleitobjekt führt zu dem obigen Fehler. Sie können einen benutzerdefinierten Setter mit der folgenden Methode schreiben.

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

Sie können auch die Erweiterungsfunktionen von Kotlin verwenden.

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

XML ist für Java und Kotlin gleich.

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

Geben Sie mehrere Parameter für den benutzerdefinierten Setter in Kotlin an

Mit Java könnte ich so schreiben.

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

Dies ist bei Kotlin der Fall.

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

Schreiben Sie in XML:

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

Wie unten gezeigt, funktioniert es nicht gut, wenn nur einige Parameter angegeben werden.

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

Dies liegt daran, dass das Attribut "requireAll" des BindingAdapters standardmäßig "true" ist. In diesem Fall wird es nur aufgerufen, wenn alle Parameter angegeben sind. Schreiben Sie BindingAdapter wie folgt neu, damit es von einigen Parametern aufgerufen wird.

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

Ich möchte Int, Boolean an BindingAdapter übergeben

Ich wollte Int auf BindingAdapter setzen, also schrieb ich Folgendes, aber es funktionierte nicht.

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

Die Ursache liegt in der Art und Weise, wie es in XML geschrieben ist, und es funktioniert, wenn Sie es wie folgt ändern.

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

Wenn Sie einen Booleschen Wert übergeben möchten, schreiben Sie:

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

Ich weiß nicht, warum ich das schreiben muss, also lass es mich wissen, wenn jemand es weiß.

Ich möchte die Ressourcen-ID an BindingAdapter übergeben

Sie können die R-Klasse wie folgt importieren.

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

Ich möchte andere Ereignisse als android: onClick behandeln

Zuerst habe ich überprüft, ob standardmäßig ein Adapter vorhanden ist. https://android.googlesource.com/platform/frameworks/data-binding/+/master/extensions/baseAdapters/src/main/java/android/databinding/adapters

Wenn Sie beispielsweise "android: onTextChanged" von "EditTextView" verwenden möchten, TextViewBindingAdapter.java (main / java / android / database / adapters / TextViewBindingAdapter.java) verfügt bereits über einen BindingAdapter, sodass Sie ihn verwenden können.

Hier finden Sie auch eine Beschreibung von BindingMethod, sodass Sie sich möglicherweise nicht die Mühe machen müssen, eine BindingMethod-Methode wie set ** Listener vorzubereiten.

Ich möchte den Kontext als Argument verwenden

Als ich eine Methode verwenden wollte, die Context als Argument in DataBinding hat, habe ich auf den folgenden Artikel verwiesen. Wenn Sie "Kontext" so wie es ist übergeben, wird es funktionieren.

Behandeln Sie eine Methode, die den Kontext als Argument in DataBinding übergibt

Recommended Posts

Stolpern Sie mit Android DataBinding + Kotlin (mehr BindingAdapter)
Ich habe eine Taschenrechner-App für Android erstellt
Ich habe versucht, "nifty cloud mobile backend" und "Firebase" -Authentifizierung auf Kotlin + Android zu verwenden
Ich bin auf die Java-Version in Android Studio gestoßen, daher werde ich sie zusammenfassen
[Android Studio] Ich möchte eine Maven-Bibliothek unter Android verwenden
Ich habe eine Bibliothek zum Anzeigen von Tutorials auf Android erstellt.
Worauf ich bei der Installation von Ruby unter Ubuntu gestoßen bin
Ich möchte die Protokollausgabe unter Android vereinfachen