associazione dati Android utilizzando l'operatore logico "&&"


132

Sto cercando di utilizzare l'operatore and "&&" in xml utilizzando l'associazione dati Android,

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

ma ho ricevuto l'errore di compilazione:

Errore: esecuzione non riuscita per l'attività ": 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; Il nome dell'entità deve seguire immediatamente la "&" nel riferimento all'entità.

e l'errore di evidenziazione in rosso in Android Studio "carattere senza caratteri di escape e o non terminato".

Quindi come dovrei risolvere questo problema?

Modifica: trovata la risposta, questi caratteri devono essere scappati:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Ho notato che posso usare ">" e "<" nei file xml di layout.
Hong

Risposte:


234

&&dovrebbe essere reso come &amp;&amp;.

La guida ufficiale del data binding contiene esempi di operatori di confronto in cui vengono utilizzate queste entità XML, ad esempio

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

modificare

Le espressioni di esempio che ho menzionato nella risposta sono scomparse dalla versione inglese dei documenti poiché questa risposta è stata scritta. Sopravvivono in alcune versioni non in inglese obsolete dei documenti come la versione spagnola.

In ogni caso, la risposta originale è ancora valida, perché l'uso di entità XML in XML è standard in XML e non ha nulla a che fare con Android stesso.


12
Non utilizzare la logica di dominio nelle espressioni di associazione, hai preseters / controller per questo.
artkoenig

2
@ ArtjomKönig e se devi nascondere / mostrare alcuni controlli nell'interfaccia utente? Uso la libreria di data binding per NON scrivere il codice dell'interfaccia utente
Krusty

3
@Krusty Imlement è un metodo isMyControlVisible () nel presentatore, in cui si utilizza la logica del dominio per restituire vero o falso. Legati a questo metodo.
artkoenig

1
Penso che se hai troppe variabili booleane questa soluzione va bene. Altrimenti il ​​tuo codice avrebbe un sacco di ObservableBoolean.set
Lester

@artkoenig allora dovresti mantenere quei booleani extra ovunque tu faccia riferimento al layout. Fonte di bug.
Ali Kazi

36

Elenco di entità HTML

Non puoi usare & o qualche altra entità HTML in XML. Quindi devi usare il carattere di fuga.

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

Entità carattere HTML spesso utilizzate in Android:

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

Ecco un elenco completo di entità HTML.


17

L'escape di && nel markup del layout è una soluzione molto scarsa. È meglio creare un metodo sull'oggetto del modello (visualizzazione):

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

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

4
Sebbene questa sia una buona soluzione, purtroppo non viene richiamata quando il valore della variabile cambia (notifyPropertyChanged) e la visibilità non verrà aggiornata.
Bernd Kampl

2
@BerndKampl UseObservableBoolean isAdult
S1ngoooor

Non funzionerà, verrà chiamato solo una volta!
CodingTT

@BerndKampl come usarlo, viene ancora chiamato una volta
CodingTT

@CodingTT guarda la mia risposta, avrai bisogno di una chiamata notifyPropertyChanged da qualche parte per aggiornarla.
Bernd Kampl

3

La migliore soluzione che ho potuto trovare per questo problema è stata l'introduzione di un nuovo metodo Bindable.

Prima:

item_recyclerview.xml:

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

MyDataModelClass: (che si tiene nel mio viewmodel)

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

Dopo:

item_recyclerview.xml:

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

MyDataModelClass: (che si tiene nel mio viewmodel)

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

Quel codice utilizza le classi BaseObservable, BR è la classe di associazione generata. Vedi questo post per una spiegazione più dettagliata: medium.com/@jencisov/…
Bernd Kampl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.