「&&」論理演算子を使用した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:file:/Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; lineNumber:106; columnNumber:89; エンティティー名は、エンティティー参照の「&」の直後に続く必要があります。

Androidスタジオの赤いハイライトエラー「エスケープされていない、または終端されていない文字」。

どうすればこれを修正できますか?

編集: 答えを見つけました、これらの文字はエスケープする必要があります:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

レイアウトxmlファイルで ">"および "<"を使用できることに気づきました。
香港

回答:


233

&&としてレンダリングする必要があります&amp;&amp;

公式のデータバインディングガイドには、これらのXMLエンティティが使用される比較演算子の例が含まれています。

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

編集する

私が回答で述べた式の例は、この回答が書かれたため、英語版のドキュメントから姿を消しました。彼らはスペイン語版のようないくつかの古い非英語版のドキュメントで生き残ります。

どちらの方法でも、XMLでのXMLエンティティの使用はXMLの標準であり、Android自体とは関係がないため、元の回答は引き続き有効です。


12
バインディング式でドメインロジックを使用しないでください。このためのプリセッター/コントローラーがあります。
artkoenig 2017年

2
@ArtjomKönigUIで一部のコントロールを非表示/表示する必要がある場合はどうですか?データバインディングライブラリを使用してUIコードを記述しない
Krusty

3
@Krustyドメインロジックを使用してtrueまたはfalseを返すプレゼンターのメソッドisMyControlVisible()を実装します。このメソッドにバインドします。
artkoenig

1
ブール変数が多すぎる場合、この解決策は問題ないと思います。それ以外の場合、コードにはたくさんのObservableBoolean.setがあります
Lester

@artkoenigでは、レイアウトを参照するすべての場所でこれらの追加のブール値を維持する必要があります。バグの原因。
Ali Kazi

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

レイアウトマークアップで&&をエスケープすることは、非常に貧弱なソリューションです。(ビュー)モデルオブジェクトにメソッドを作成することをお勧めします:

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

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

4
これは良い解決策ですが、残念ながら、変数の値が変更され(notifyPropertyChanged)、可視性が更新されない場合は呼び出されません。
Bernd Kampl 2016

2
@BerndKamplの使用ObservableBoolean isAdult
S1ngoooor 2017年

これは機能しません。呼び出されるのは1回だけです。
CodingTT 2018

@BerndKamplそれを使用する方法、それはまだ一度呼び出されます
CodingTT

@CodingTT私の回答を見てください、それを更新するには、どこかにnotifyPropertyChanged呼び出しが必要です。
Bernd Kampl 2018年

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
Bernd Kampl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.