привязка данных Android с помощью логического оператора «&&»


132

Я пытаюсь использовать оператор и "&&" в xml, используя привязку данных Android,

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

но я получил ошибку компиляции:

Ошибка: не удалось выполнить задачу ': 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; Имя объекта должно сразу следовать за символом "&" в ссылке на объект.

и красная ошибка выделения в студии Android «неэкранированный и или не завершенный символ».

Так как мне это исправить?

Изменить: нашел ответ, нужно экранировать этот символ:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Я заметил, что могу использовать ">" и "<" в файлах макета xml.
Гонконг

Ответы:


234

&&должен отображаться как &amp;&amp;.

В официальном руководстве по привязке данных есть примеры операторов сравнения, в которых используются эти XML-сущности, например

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

редактировать

Примеры выражений, которые я упомянул в ответе, исчезли из английской версии документов, так как этот ответ был написан. Они действительно сохранились в некоторых устаревших неанглоязычных версиях документов, например в испанской.

В любом случае исходный ответ по-прежнему действителен, поскольку использование сущностей XML в XML является стандартом для XML и не имеет ничего общего с самим Android.


12
Не используйте логику домена в выражениях привязки, для этого у вас есть презетеры / контроллеры.
artkoenig 09

2
@ ArtjomKönig, а что если вам нужно скрыть / показать некоторые элементы управления в пользовательском интерфейсе? Я использую библиотеку привязки данных, чтобы НЕ писать код пользовательского интерфейса
Красти

3
@Krusty Внедрите метод isMyControlVisible () в своем презентаторе, где вы используете логику своего домена, чтобы вернуть обратно истину или ложь. Привяжите к этому методу.
artkoenig

1
Я думаю, что если у вас слишком много логических переменных, это решение подойдет. В противном случае в вашем коде было бы много ObservableBoolean.set
Лестер,

@artkoenig, тогда вам придется поддерживать эти дополнительные логические значения везде, где вы ссылаетесь на макет. Источник ошибок.
Али Кази

36

Список объектов HTML

Вы не можете использовать & или какой-либо другой объект HTML в XML. Итак, вам нужно использовать экранирующий символ.

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

Сущности символов HTML, часто используемые в Android:

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

Вот полный список объектов HTML.


17

Экранирование && в разметке макета - очень плохое решение. Лучше создать метод на объекте модели (view):

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

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

4
Хотя это хорошее решение, оно, к сожалению, не вызывается при изменении значения переменной (notifyPropertyChanged) и видимость не обновляется.
Бернд Кампл

2
@BerndKampl UseObservableBoolean isAdult
S1ngoooor

Это не сработает, оно будет вызвано только один раз!
CodingTT

@BerndKampl, как его использовать, он все равно вызывается один раз
CodingTT

@CodingTT посмотрите мой ответ, вам понадобится вызов notifyPropertyChanged где-нибудь, чтобы обновить его.
Бернд Кампл

3

Лучшее решение, которое я мог придумать для этой проблемы, - это введение нового метода Bindable.

Перед:

item_recyclerview.xml:

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

MyDataModelClass: (который проводится в моей модели просмотра)

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

После:

item_recyclerview.xml:

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

MyDataModelClass: (который проводится в моей модели просмотра)

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

Этот код использует классы BaseObservable, BR - это сгенерированный класс привязки. См. Этот пост для более подробного объяснения: medium.com/@jencisov/…
Бернд Кампл
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.