使用“ &&”逻辑运算符的android数据绑定


131

我正在尝试使用Android数据绑定在xml中使用and“ &&”运算符,

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;lineNumber:106;columnNumber:89;实体名称必须紧随实体引用中的“&”之后。

和红色突出显示Android Studio中的错误“未转义和/或未终止的字符”。

那么我该如何解决呢?

编辑: 找到答案,这些字符需要转义:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

我注意到我可以在布局xml文件中使用“>”和“ <”。

Answers:


233

&&应该呈现为&amp;&amp;

官方数据绑定指南包含使用这些XML实体的比较运算符的示例,例如

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

编辑

自从撰写此答案以来,我在答案中提到的示例表达式就从文档的英文版中消失了。它们确实可以在一些过时的非英语版本文档中生存,例如西班牙语版本。

无论哪种方式,原始答案仍然有效,因为在XML中使用XML实体是XML的标准,与Android本身无关。


12
不要在绑定表达式中使用域逻辑,您可以为此使用预置器/控制器。
artkoenig

2
@ArtjomKönig如果必须在UI中隐藏/显示某些控件,该怎么办?我使用数据绑定库不编写UI代码
Krusty

3
@Krusty在演示者中实现isMyControlVisible()方法,在此您可以使用域逻辑返回true或false。绑定到此方法。
artkoenig

1
我认为如果布尔变量太多,此解决方案就可以了。否则,您的代码将具有大量的ObservableBoolean.set
Lester,

@artkoenig,那么您必须在引用布局的所有地方都保留那些额外的布尔值。错误来源。
阿里·卡兹

36

HTML实体清单

您不能在XML中使用或其他HTML实体。因此,您必须使用转义字符。

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

Android中经常使用的HTML字符实体:

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

是HTML实体的完整列表。


17

在布局标记中转义&&是一个非常差的解决方案。最好在(view)model对象上创建一个方法:

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

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

4
尽管这是一个很好的解决方案,但是不幸的是,当变量值更改(notifyPropertyChanged)并且可见性不会更新时,不会调用它。
Bernd Kampl

2
@BerndKampl使用ObservableBoolean isAdult
S1ngoooor

这行不通,只会被调用一次!
CodingTT '18

@BerndKampl如何使用它,它仍然被调用过一次
CodingTT '18

@CodingTT看看我的答案,您将需要在某个地方进行notifyPropertyChanged调用来对其进行更新。
伯纳德·坎普

3

对于这个问题,我能想到的最佳解决方案是引入新的Bindable方法。

之前:

item_recyclerview.xml

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

MyDataModelClass:(正在我的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);
}

后:

item_recyclerview.xml

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

MyDataModelClass:(正在我的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();
}

该代码使用BaseObservable类,BR是生成的绑定类。看到这个帖子了更详细的解释:medium.com/@jencisov/...
贝恩德Kampl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.