wiązanie danych z systemem Android przy użyciu operatora logicznego „&&”

131

Próbuję użyć operatora and „&&” w xml przy użyciu wiązania danych Androida,

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

ale dostałem błąd kompilacji:

Błąd: nie powiodło się wykonanie zadania „: app: dataBindingProcessLayoutsDevDebug”. org.xml.sax.SAXParseException; systemId: file: /Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; lineNumber: 106; columnNumber: 89; Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki.

i czerwony błąd podświetlenia w Android Studio „znak niezakończony i lub niezakończony”.

Więc jak mam to naprawić?

Edycja: znalazłem odpowiedź, tę postać należy uciec:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'
David Cheung
źródło
Zauważyłem, że mogę używać znaków „>” i „<” w plikach XML układu.
Hong

Odpowiedzi:

234

&&powinien być renderowany jako &amp;&amp;.

Oficjalny przewodnik po wiązaniu danych zawiera przykłady operatorów porównania, w których są używane na przykład te jednostki XML

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

Edytować

Przykładowe wyrażenia, o których wspomniałem w odpowiedzi, zniknęły z angielskiej wersji dokumentacji od czasu napisania tej odpowiedzi. Przetrwają w niektórych przestarzałych nieanglojęzycznych wersjach dokumentów, takich jak wersja hiszpańska.

Tak czy inaczej, oryginalna odpowiedź jest nadal ważna, ponieważ użycie jednostek XML w XML jest standardem w XML i nie ma nic wspólnego z samym Androidem.

Leo wspiera Monikę Cellio
źródło
12
Nie używaj logiki domeny w wyrażeniach wiążących, masz do tego presetery / kontrolery.
artkoenig
2
@ ArtjomKönig A co jeśli musisz ukryć / pokazać niektóre elementy sterujące w interfejsie użytkownika? Używam biblioteki powiązań danych, aby NIE pisać kodu interfejsu użytkownika
Krusty
3
@Krusty Imlement to metoda isMyControlVisible () w Twoim prezencie, w której używasz logiki domeny, aby zwrócić prawdę lub fałsz. Powiąż z tą metodą.
artkoenig
1
Myślę, że jeśli masz zbyt wiele zmiennych boolowskich, to rozwiązanie jest w porządku. W przeciwnym razie twój kod miałby dużo ObservableBoolean.set
Lester
@artkoenig, wtedy musisz zachować te dodatkowe wartości logiczne wszędzie tam, gdzie odnosisz się do układu. Źródło błędów.
Ali Kazi,
36

Lista encji HTML

Nie możesz używać & ani innej jednostki HTML w XML. Musisz więc użyć uciekającego znaku.

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

Jednostki znaków HTML często używane w systemie Android:

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

Oto pełna lista encji HTML.

Khemraj
źródło
17

Unikanie znaku && w znaczniku układu jest bardzo kiepskim rozwiązaniem. Lepiej jest utworzyć metodę na obiekcie modelu (widok):

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

public boolean isAdult() {
    return age >= 18;
}
Ollie C
źródło
4
Chociaż jest to dobre rozwiązanie, niestety nie jest wywoływane, gdy zmienia się wartość zmiennej (notifyPropertyChanged), a widoczność nie zostanie zaktualizowana.
Bernd Kampl
2
@BerndKampl UseObservableBoolean isAdult
S1ngoooor
To nie zadziała, zostanie wywołane tylko raz!
CodingTT
@BerndKampl, jak go używać, nadal jest wywoływany raz
CodingTT
@CodingTT spójrz na moją odpowiedź, będziesz potrzebować wywołania notifyPropertyChanged gdzieś, aby go zaktualizować.
Bernd Kampl
3

Najlepszym rozwiązaniem, jakie mogłem wymyślić dla tego problemu, było wprowadzenie nowej metody Bindable.

Przed:

item_recyclerview.xml:

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

MyDataModelClass: (który jest przechowywany w moim modelu widoku)

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

Po:

item_recyclerview.xml:

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

MyDataModelClass: (który jest przechowywany w moim modelu widoku)

...
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();
}
Bernd Kampl
źródło
Ten kod używa klas BaseObservable, BR jest wygenerowaną klasą powiązania. Zobacz ten post, aby uzyskać bardziej szczegółowe wyjaśnienie: medium.com/@jencisov/…
Bernd Kampl