liaison de données Android à l'aide de l'opérateur logique «&&»

132

J'essaie d'utiliser l'opérateur et "&&" dans XML en utilisant la liaison de données Android,

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

mais j'ai eu l'erreur de compilation:

Erreur: l'exécution a échoué pour la tâche «: app: dataBindingProcessLayoutsDevDebug». org.xml.sax.SAXParseException; systemId: fichier: /Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; lineNumber: 106; columnNumber: 89; Le nom de l'entité doit immédiatement suivre le «&» dans la référence de l'entité.

et erreur de surbrillance rouge dans le studio Android "caractère non échappé et ou non terminé".

Alors, comment dois-je résoudre ce problème?

Edit: trouvé la réponse, ces caractères doivent être échappés:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'
David Cheung
la source
J'ai remarqué que je peux utiliser ">" et "<" dans les fichiers xml de mise en page.
Hong

Réponses:

234

&&doit être rendu comme &amp;&amp;.

Le guide officiel de liaison de données contient des exemples d'opérateurs de comparaison où ces entités XML sont utilisées, par exemple

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

Éditer

Les exemples d'expressions que j'ai mentionnés dans la réponse ont disparu de la version anglaise de la documentation depuis que cette réponse a été écrite. Ils survivent dans certaines versions non anglaises obsolètes de la documentation, comme la version espagnole.

Quoi qu'il en soit, la réponse d'origine est toujours valable, car l'utilisation d'entités XML dans XML est standard dans XML et n'a rien à voir avec Android lui-même.

Leo soutient Monica Cellio
la source
12
N'utilisez pas la logique de domaine dans les expressions de liaison, vous avez des préréglages / contrôleurs pour cela.
artkoenig
2
@ ArtjomKönig et si vous devez masquer / afficher certains contrôles dans l'interface utilisateur? J'utilise la bibliothèque de liaison de données pour ne PAS écrire de code d'interface utilisateur
Krusty
3
@Krusty Imlement une méthode isMyControlVisible () dans votre présentateur, où vous utilisez la logique de votre domaine pour renvoyer vrai ou faux. Liez à cette méthode.
artkoenig
1
Je pense que si vous avez trop de variables booléennes, cette solution convient. Sinon, votre code aurait beaucoup de ObservableBoolean.set
Lester
@artkoenig alors vous devrez maintenir ces booléens supplémentaires partout où vous faites référence à la mise en page. Source de bugs.
Ali Kazi
36

Liste des entités HTML

Vous ne pouvez pas utiliser & ou une autre entité HTML dans XML. Vous devez donc utiliser un caractère d'échappement.

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

Entités de caractères HTML souvent utilisées dans Android:

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

Voici une liste complète des entités HTML.

Khemraj
la source
17

Échapper à && dans le balisage de mise en page est une très mauvaise solution. Il est préférable de créer une méthode sur l'objet de modèle (vue):

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

public boolean isAdult() {
    return age >= 18;
}
Ollie C
la source
4
Bien que ce soit une bonne solution, elle n'est malheureusement pas appelée lorsque la valeur de la variable change (notifyPropertyChanged) et la visibilité ne sera pas mise à jour.
Bernd Kampl
2
@BerndKampl UseObservableBoolean isAdult
S1ngoooor
Cela ne fonctionnera pas, il ne sera appelé qu'une seule fois!
CodingTT
@BerndKampl comment l'utiliser, il est toujours appelé une fois
CodingTT
@CodingTT regarde ma réponse, vous aurez besoin d'un appel notifyPropertyChanged quelque part pour la mettre à jour.
Bernd Kampl
3

La meilleure solution que j'ai pu trouver pour ce problème était l'introduction d'une nouvelle méthode de liaison.

Avant:

item_recyclerview.xml:

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

MyDataModelClass: (qui se déroule dans mon modèle de vue)

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

Après:

item_recyclerview.xml:

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

MyDataModelClass: (qui se déroule dans mon modèle de vue)

...
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
la source
Ce code utilise des classes BaseObservable, BR est la classe de liaison générée. Voir cet article pour une explication plus détaillée: medium.com/@jencisov/…
Bernd Kampl