penyatuan data android menggunakan operator logika “&&”


132

Saya mencoba menggunakan operator dan "&&" di xml menggunakan penyatuan data Android,

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

tapi saya mendapat kesalahan kompilasi:

Kesalahan: Eksekusi gagal untuk tugas ': app: dataBindingProcessLayoutsDevDebug'. org.xml.sax.SAXParseException; systemId: file: /Users/path/app/build/intermediates/res/merged/dev/debug/layout/fragment_space.xml; barisNomor: 106; kolomNomor: 89; Nama entitas harus segera mengikuti '&' di referensi entitas.

dan kesalahan sorotan merah di studio android "karakter yang tidak lolos & atau tidak dihentikan".

Jadi bagaimana saya harus memperbaikinya?

Sunting: temukan jawabannya, karakter ini perlu diloloskan:

'&' --> '&'

'<' --> '&lt;'

'>' --> '&gt;'

Saya perhatikan bahwa saya dapat menggunakan ">" dan "<" dalam file layout xml.
Hong

Jawaban:


234

&&harus dirender sebagai &amp;&amp;.

Panduan pengikatan data resmi memiliki contoh operator perbandingan di mana entitas XML ini digunakan, misalnya

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

Sunting

Contoh ekspresi yang saya sebutkan dalam jawaban menghilang dari versi bahasa Inggris dari dokumen sejak jawaban ini ditulis. Mereka bertahan di beberapa dokumen versi non-Inggris yang sudah ketinggalan zaman seperti versi bahasa Spanyol.

Bagaimanapun, jawaban asli masih valid, karena penggunaan entitas XML dalam XML adalah standar dalam XML dan tidak ada hubungannya dengan Android itu sendiri.


12
Jangan gunakan logika domain dalam ekspresi binding, Anda memiliki preseter / pengontrol untuk ini.
artkoenig

2
@ ArtjomKönig bagaimana jika Anda harus menyembunyikan / menampilkan beberapa kontrol di UI? Saya menggunakan perpustakaan data mengikat untuk TIDAK menulis kode UI
Krusty

3
@Krusty Menerapkan metode isMyControlVisible () di presenter Anda, di mana Anda menggunakan logika domain untuk mengembalikan benar atau salah. Ikat ke metode ini.
artkoenig

1
Saya rasa Jika Anda memiliki terlalu banyak variabel boolean solusi ini baik-baik saja. Jika tidak, kode Anda akan memiliki banyak ObservableBoolean.set
Lester

@artkoenig maka Anda harus mempertahankan boolean ekstra tersebut di mana pun Anda merujuk ke tata letak. Sumber bug.
Ali Kazi

36

Daftar entitas HTML

Anda tidak dapat menggunakan & atau entitas HTML lain dalam XML. Jadi Anda harus menggunakan karakter melarikan diri.

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

Entitas Karakter HTML yang sering digunakan di Android:

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

Berikut adalah daftar lengkap entitas HTML.


17

Melarikan diri && dalam mark-up tata letak adalah solusi yang sangat buruk. Lebih baik membuat metode pada objek model (view):

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

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

4
Meskipun ini adalah solusi yang baik, sayangnya tidak dipanggil ketika nilai variabel berubah (notifyPropertyChanged) dan visibilitas tidak akan diperbarui.
Bernd Kampl

2
Penggunaan @BerndKamplObservableBoolean isAdult
S1ngoooor

Ini tidak akan berhasil, ini hanya akan dipanggil sekali!
CodingTT

@BerndKampl bagaimana menggunakannya, itu masih dipanggil sekali
CodingTT

@CodingTT lihat Jawaban saya, Anda akan memerlukan panggilan notifyPropertyChanged di suatu tempat untuk memperbaruinya.
Bernd Kampl

3

Solusi terbaik yang dapat saya temukan untuk masalah ini adalah memperkenalkan metode Bindable baru.

Sebelum:

item_recyclerview.xml:

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

MyDataModelClass: (yang diadakan di viewmodel saya)

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

Setelah:

item_recyclerview.xml:

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

MyDataModelClass: (yang diadakan di viewmodel saya)

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

Kode itu menggunakan kelas BaseObservable, BR adalah kelas mengikat yang dihasilkan. Lihat posting ini untuk penjelasan lebih rinci: medium.com/@jencisov/…
Bernd Kampl
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.