Android-Datenbindung mit dem logischen Operator "&&"


131

Ich versuche, den Operator und "&&" in XML mithilfe der Android-Datenbindung zu verwenden.

android:visibility="@{(bean.currentSpaceId == bean.selectedSpaceId **&&** bean.currentSpaceId > 0)? View.VISIBLE: View.GONE}"

aber ich habe den Kompilierungsfehler bekommen:

Fehler: Ausführung für Task ': app: dataBindingProcessLayoutsDevDebug' fehlgeschlagen. org.xml.sax.SAXParseException; systemId: file: /Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; lineNumber: 106; columnNumber: 89; Der Entitätsname muss unmittelbar auf das '&' in der Entitätsreferenz folgen.

und rote Markierung Fehler in Android Studio "unescaped & oder nicht terminierte Zeichen".

Wie soll ich das beheben?

Bearbeiten: fand die Antwort, diese Zeichen müssen maskiert werden:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Ich habe festgestellt, dass ich ">" und "<" in Layout-XML-Dateien verwenden kann.
Hong

Antworten:


233

&&sollte als gerendert werden &amp;&amp;.

Der offizielle Leitfaden zur Datenbindung enthält Beispiele für Vergleichsoperatoren, bei denen diese XML-Entitäten beispielsweise verwendet werden

android:visibility="@{age &lt; 13 ? View.GONE : View.VISIBLE}"

Bearbeiten

Die Beispielausdrücke, die ich in der Antwort erwähnt habe, sind aus der englischen Version der Dokumente verschwunden, da diese Antwort geschrieben wurde. Sie überleben in einigen veralteten nicht-englischen Versionen der Dokumente wie der spanischen Version.

In beiden Fällen ist die ursprüngliche Antwort weiterhin gültig, da die Verwendung von XML-Entitäten in XML in XML Standard ist und nichts mit Android selbst zu tun hat.


12
Verwenden Sie keine Domänenlogik zum Binden von Ausdrücken, Sie haben hierfür Preseter / Controller.
Artkoenig

2
@ ArtjomKönig was ist, wenn Sie einige Steuerelemente in der Benutzeroberfläche ausblenden / anzeigen müssen? Ich benutze Datenbindungsbibliothek, um NICHT UI-Code zu schreiben
Krusty

3
@Krusty Imlement ist eine Methode isMyControlVisible () in Ihrem Präsentator, bei der Sie Ihre Domänenlogik verwenden, um true oder false zurückzugeben. Binden Sie an diese Methode.
Artkoenig

1
Ich denke, wenn Sie zu viele boolesche Variablen haben, ist diese Lösung in Ordnung. Andernfalls hätte Ihr Code viel ObservableBoolean.set
Lester

@artkoenig dann müssten Sie diese zusätzlichen Booleschen Werte überall dort beibehalten, wo Sie auf das Layout verweisen. Quelle von Fehlern.
Ali Kazi

36

Liste der HTML-Entitäten

Sie können & oder eine andere HTML-Entität in XML nicht verwenden. Sie müssen also einen Escape-Charakter verwenden.

android:text="@{(1==1 &amp;&amp; 2>0) ? `true` : `false`}"

In Android häufig verwendete HTML-Zeichenentitäten:

+--------+----------------------------+--+--+--+
| Symbol | Equivalent HTML Entity     |  |  |  |
+--------+----------------------------+--+--+--+
| >      | &gt;                       |  |  |  |
+--------+----------------------------+--+--+--+
| <      | &lt;                       |  |  |  |
+--------+----------------------------+--+--+--+
| "      | &quot;, &ldquo; or &rdquo; |  |  |  |
+--------+----------------------------+--+--+--+
| '      | &apos;, &lsquo; or &rsquo; |  |  |  |
+--------+----------------------------+--+--+--+
| }      | &#125;                     |  |  |  |
+--------+----------------------------+--+--+--+
| &      | &amp;                      |  |  |  |
+--------+----------------------------+--+--+--+
| space  | &#160;                     |  |  |  |
+--------+----------------------------+--+--+--+

Hier ist eine vollständige Liste der HTML-Entitäten.


17

Das Entkommen von && im Layout-Markup ist eine sehr schlechte Lösung. Es ist besser, eine Methode für das (Ansichts-) Modellobjekt zu erstellen:

android:visibility="@{user.adult ? View.VISIBLE : View.GONE}"

public boolean isAdult() {
    return age >= 18;
}

4
Dies ist zwar eine gute Lösung, wird jedoch leider nicht aufgerufen, wenn sich der Variablenwert ändert (notifyPropertyChanged) und die Sichtbarkeit nicht aktualisiert wird.
Bernd Kampl

2
@BerndKampl VerwendungObservableBoolean isAdult
S1ngoooor

Dies wird nicht funktionieren, es wird nur einmal aufgerufen!
CodingTT

@BerndKampl wie man es benutzt, es wird immer noch einmal aufgerufen
CodingTT

@CodingTT Schauen Sie sich meine Antwort an. Sie benötigen irgendwo einen Aufruf von notifyPropertyChanged, um sie zu aktualisieren.
Bernd Kampl

3

Die beste Lösung, die ich für dieses Problem finden konnte, war die Einführung einer neuen bindbaren Methode.

Vor:

item_recyclerview.xml::

<EditText
...
android:enabled="@{myViewModel.myDataModelClass.lastAddedItem &amp;&amp; !myViewModel.myDataModelClass.editTextDisabled}"
/>

MyDataModelClass: (was in meinem Ansichtsmodell gehalten wird)

...
private boolean lastAddedItem;
private boolean editTextDisabled;
...
@Bindable
public boolean isLastAddedItem() {
    return lastAddedItem;
}
public void setLastAddedItem(boolean lastAddedItem) {
    this.lastAddeditem = lastAddedItem;
    notifyPropertyChanged(BR.lastAddedItem);
}
@Bindable
public boolean isEditTextDisabled() {
    return editTextDisabled;
}
public void setEditTextDisabled(boolean editTextDisabled) {
    this.editTextDisabled = editTextDisabled;
    notifyPropertyChanged(BR.editTextDisabled);
}

Nach dem:

item_recyclerview.xml::

<EditText
...
android:enabled="@{myViewModel.myDataModelClass.enableEditing}"
/>

MyDataModelClass: (was in meinem Ansichtsmodell gehalten wird)

...
private boolean lastAddedItem;
private boolean editTextDisabled;
...
@Bindable
public boolean isLastAddedItem() {
    return lastAddedItem;
}
public void setLastAddedItem(boolean lastAddedItem) {
    this.lastAddeditem = lastAddedItem;
    notifyPropertyChanged(BR.lastAddedItem);
    notifyPropertyChanged(BR.isEnableEditing);
}
@Bindable
public boolean isEditTextDisabled() {
    return editTextDisabled;
}
public void setEditTextDisabled(boolean editTextDisabled) {
    this.editTextDisabled = editTextDisabled;
    notifyPropertyChanged(BR.editTextDisabled);
    notifyPropertyChanged(BR.isEnableEditing);
}
@Bindable
public boolean isEnableEditing() {
    return isLastAddedItem() && !isEditTextDisabled();
}

Dieser Code verwendet BaseObservable-Klassen, BR ist die generierte Bindungsklasse. Eine ausführlichere Erklärung finden Sie in diesem Beitrag: medium.com/@jencisov/…
Bernd Kampl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.