ligação de dados do Android usando o operador lógico “&&”


131

Estou tentando usar o operador "&&" no xml usando a ligação de dados do Android,

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

mas recebi o erro de compilação:

Erro: falha na execução da tarefa ': 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; O nome da entidade deve seguir imediatamente o '&' na referência da entidade.

e erro de destaque vermelho no android studio "caractere sem escape e / ou não encerrado".

Então, como devo corrigir isso?

Edit: encontrou a resposta, este caractere precisa ser escapado:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Percebi que posso usar ">" e "<" nos arquivos xml de layout.
21719 Hong

Respostas:


233

&&deve ser renderizado como &amp;&amp;.

O guia oficial de ligação de dados possui exemplos de operadores de comparação nos quais essas entidades XML são usadas, por exemplo

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

Editar

As expressões de exemplo que eu mencionei na resposta desapareceram da versão em inglês dos documentos desde que essa resposta foi escrita. Eles sobrevivem em algumas versões desatualizadas dos documentos, em inglês, como a versão em espanhol.

De qualquer forma, a resposta original ainda é válida, porque o uso de entidades XML em XML é padrão em XML e não tem nada a ver com o próprio Android.


12
Não use lógica de domínio em expressões de ligação, você tem pré-parâmetros / controladores para isso.
artkoenig

2
@ ArtjomKönig, e se você precisar ocultar / mostrar alguns controles na interface do usuário? Eu uso de dados biblioteca de ligação não escrever código UI
Krusty

3
@Krusty Imlement, um método isMyControlVisible () no seu apresentador, onde você usa sua lógica de domínio para retornar retorno verdadeiro ou falso. Vincule a esse método.
artkoenig

1
Eu acho que se você tiver muitas variáveis ​​booleanas, essas soluções serão boas. Caso contrário, seu código teria bastante ObservableBoolean.set
Lester

@artkoenig, você teria que manter esses booleanos extras em todos os lugares em que se referir ao layout. Fonte de bugs.
Ali Kazi

36

Lista de entidades HTML

Você não pode usar & ou alguma outra entidade HTML em XML. Então você tem que usar caracteres de escape.

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

Entidades de caracteres HTML frequentemente usadas no Android:

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

Aqui está uma lista completa de entidades HTML.


17

Escapar && na marcação do layout é uma solução muito ruim. É melhor criar um método no objeto de modelo (de exibição):

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

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

4
Embora essa seja uma boa solução, infelizmente não é chamada quando o valor da variável é alterado (notifyPropertyChanged) e a visibilidade não será atualizada.
precisa

2
@BerndKampl UseObservableBoolean isAdult
S1ngoooor 4/17

Isso não vai funcionar, será chamado apenas uma vez!
CodingTT

@BerndKampl como usá-lo, ainda é ficar chamado uma vez
CodingTT

@CodingTT olha minha resposta, você precisará de uma chamada notifyPropertyChanged em algum lugar para atualizá-la.
precisa

3

A melhor solução que eu consegui encontrar para esse problema foi a introdução de um novo método Bindable.

Antes:

item_recyclerview.xml:

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

MyDataModelClass: (que está sendo realizado no meu 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);
}

Depois de:

item_recyclerview.xml:

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

MyDataModelClass: (que está sendo realizado no meu 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();
}

Esse código está usando as classes BaseObservable, BR é a classe de ligação gerada. Veja este post para uma explicação mais detalhada: medium.com/@jencisov/…
Bernd Kampl
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.