зв'язування даних з Android за допомогою логічного оператора “&&”


131

Я намагаюся використовувати оператор "і&" у xml за допомогою прив'язки даних Android,

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

але я отримав помилку компіляції:

Помилка: Не вдалося виконати завдання ': app: dataBindingProcessLayoutsDevDebug'. org.xml.sax.SAXParseException; systemId: файл: /Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; рядокNumber: 106; колонкаНомера: 89; Ім'я об'єкта повинно негайно слідувати "&" у посиланні на сутність.

і червона помилка підсвічування в андроїд-студії "без націлених та не припинених символів".

То як я можу це виправити?

Редагувати: знайшов відповідь, цих символів потрібно уникнути:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Я помітив, що я можу використовувати ">" та "<" у макеті файлів xml.
Гонг

Відповіді:


234

&&має бути надано як &amp;&amp;.

В офіційному посібнику з прив'язки даних є приклади операторів порівняння, наприклад, де використовуються ці об'єкти XML

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

Редагувати

Приклади виразів, про які я згадував у відповіді, зникли з англійської версії документів, оскільки ця відповідь була написана. Вони виживають у застарілих не англійських версіях документів, таких як іспанська версія.

Так чи інакше, оригінальна відповідь все ще справедлива, оскільки використання об'єктів XML у XML є стандартним для XML і не має нічого спільного з самим Android.


12
Не використовуйте логіку домену в обов'язкових виразах, для цього у вас є пресетери / контролери.
artkoenig

2
@ ArtjomKönig, а як бути, якщо вам доведеться сховати / показати деякі елементи управління в інтерфейсі? Я використовую бібліотеку прив'язки даних, щоб НЕ писати код інтерфейсу
Krusty

3
@Krusty Imlement метод 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.