Utilizzando l'associazione di dati unidirezionale, puoi impostare un valore per un attributo e impostare un ascoltatore che reagisce a una modifica nell'attributo:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
L'associazione di dati bidirezionale fornisce una scorciatoia a questa procedura:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
La notazione @={}
, che include principalmente il segno "=", riceve le modifiche
ai dati della proprietà e ascolta contemporaneamente gli aggiornamenti degli utenti.
Per reagire alle modifiche nei dati di supporto, puoi rendere la tua variabile di layout un'implementazione di Observable
, in genere BaseObservable
, e utilizzare un'annotazione @Bindable
, come mostrato nel seguente snippet di codice:
Kotlin
class LoginViewModel : BaseObservable { // val data = ... @Bindable fun getRememberMe(): Boolean { return data.rememberMe } fun setRememberMe(value: Boolean) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value // React to the change. saveData() // Notify observers of a new value. notifyPropertyChanged(BR.remember_me) } } }
Java
public class LoginViewModel extends BaseObservable { // private Model data = ... @Bindable public Boolean getRememberMe() { return data.rememberMe; } public void setRememberMe(Boolean value) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value; // React to the change. saveData(); // Notify observers of a new value. notifyPropertyChanged(BR.remember_me); } } }
Poiché il metodo getter della proprietà associabile è denominato getRememberMe()
, il metodo setter corrispondente della proprietà utilizza automaticamente il nome setRememberMe()
.
Per ulteriori informazioni sull'utilizzo di BaseObservable
e @Bindable
, consulta Utilizzare
gli oggetti di dati osservabili.
Associazione di dati bidirezionale con attributi personalizzati
La piattaforma fornisce implementazioni di associazioni di dati bidirezionali per gli attributi bidirezionali più comuni e i listener di modifiche, che puoi utilizzare come parte della tua app. Se vuoi utilizzare l'associazione di dati bidirezionale con attributi personalizzati, devi utilizzare le annotazioni @InverseBindingAdapter
e @InverseBindingMethod
.
Ad esempio, se vuoi attivare l'associazione di dati bidirezionale su un attributo "time"
in una vista personalizzata denominata MyView
, completa i seguenti passaggi:
Annota il metodo che imposta il valore iniziale e si aggiorna quando il valore cambia utilizzando
@BindingAdapter
:Kotlin
@BindingAdapter("time") @JvmStatic fun setTime(view: MyView, newValue: Time) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue } }
Java
@BindingAdapter("time") public static void setTime(MyView view, Time newValue) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue; } }
Annota il metodo che legge il valore dalla vista utilizzando
@InverseBindingAdapter
:Kotlin
@InverseBindingAdapter("time") @JvmStatic fun getTime(view: MyView) : Time { return view.getTime() }
Java
@InverseBindingAdapter("time") public static Time getTime(MyView view) { return view.getTime(); }
A questo punto, l'associazione di dati sa cosa fare quando i dati cambiano (chiama il metodo annotato con @BindingAdapter
) e cosa chiamare quando cambia l'attributo vista (chiama InverseBindingListener
). Tuttavia, non sa quando o come cambia l'attributo.
Per farlo, devi impostare un listener sulla vista. Può essere un listener personalizzato associato alla visualizzazione personalizzata o un evento generico, come una perdita di stato attivo o una modifica del testo. Aggiungi l'annotazione @BindingAdapter
al metodo che imposta il listener per le modifiche nella proprietà:
Kotlin
@BindingAdapter("app:timeAttrChanged") @JvmStatic fun setListeners( view: MyView, attrChange: InverseBindingListener ) { // Set a listener for click, focus, touch, etc. }
Java
@BindingAdapter("app:timeAttrChanged") public static void setListeners( MyView view, final InverseBindingListener attrChange) { // Set a listener for click, focus, touch, etc. }
Il listener include un InverseBindingListener
come parametro. Puoi utilizzare l'InverseBindingListener
per comunicare al sistema di associazione dei dati che l'attributo è stato modificato. Il sistema può quindi iniziare a chiamare il metodo annotato utilizzando @InverseBindingAdapter
e così via.
In pratica, questo listener include alcune logiche non banali, inclusi i listener per l'associazione di dati unidirezionale. Ad esempio, vedi l'adattatore per la modifica dell'attributo di testo, TextViewBindingAdapter
.
Utenti che hanno completato una conversione
Se la variabile associata a un oggetto View
deve essere formattata, tradotta o modificata in qualche modo prima di essere visualizzata, è possibile utilizzare un oggetto Converter
.
Ad esempio, supponiamo che un oggetto EditText
mostri una data:
<EditText
android:id="@+id/birth_date"
android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
L'attributo viewmodel.birthDate
contiene un valore di tipo Long
, quindi deve essere formattato utilizzando un convertitore.
Poiché viene utilizzata un'espressione bidirezionale, deve anche essere un convertitore
inverso per consentire alla libreria di sapere come convertire la stringa fornita dall'utente
nel tipo di dati di supporto, in questo caso Long
. Questo processo viene eseguito aggiungendo l'annotazione @InverseMethod
a uno degli utenti che hanno completato una conversione e fai in modo che questa annotazione faccia riferimento al convertitore inverso. Un esempio di questa configurazione viene visualizzato nel seguente snippet di codice:
Kotlin
object Converter { @InverseMethod("stringToDate") @JvmStatic fun dateToString( view: EditText, oldValue: Long, value: Long ): String { // Converts long to String. } @JvmStatic fun stringToDate( view: EditText, oldValue: String, value: String ): Long { // Converts String to long. } }
Java
public class Converter { @InverseMethod("stringToDate") public static String dateToString(EditText view, long oldValue, long value) { // Converts long to String. } public static long stringToDate(EditText view, String oldValue, String value) { // Converts String to long. } }
Loop infiniti con associazione di dati bidirezionale
Fai attenzione a non introdurre loop infiniti quando utilizzi l'associazione di dati bidirezionale. Quando l'utente modifica un attributo, viene richiamato il metodo annotato utilizzando @InverseBindingAdapter
e il valore viene assegnato alla proprietà di supporto. Questo, a sua volta, chiamerà il metodo annotato utilizzando @BindingAdapter
, il che attiverebbe un'altra chiamata al metodo annotato utilizzando @InverseBindingAdapter
e così via.
Per questo motivo è importante interrompere possibili loop infiniti confrontando valori nuovi e vecchi nei metodi annotati utilizzando @BindingAdapter
.
Attributi bidirezionali
La piattaforma fornisce supporto integrato per l'associazione di dati bidirezionale quando utilizzi gli attributi nella seguente tabella. Per informazioni dettagliate sul modo in cui la piattaforma fornisce questo supporto, consulta le implementazioni degli adattatori di associazione corrispondenti:
Classe | Attributi | Adattatore di associazione |
---|---|---|
AdapterView
|
android:selectedItemPosition android:selection |
AdapterViewBindingAdapter
|
CalendarView |
android:date |
CalendarViewBindingAdapter
|
CompoundButton |
android:checked
|
CompoundButtonBindingAdapter
|
DatePicker
|
android:year android:month android:day |
DatePickerBindingAdapter
|
NumberPicker |
android:value
|
NumberPickerBindingAdapter
|
RadioButton
|
android:checkedButton |
RadioGroupBindingAdapter
|
RatingBar
|
android:rating
|
RatingBarBindingAdapter
|
SeekBar
|
android:progress |
SeekBarBindingAdapter
|
TabHost
|
android:currentTab |
TabHostBindingAdapter
|
TextView
|
android:text
|
TextViewBindingAdapter
|
TimePicker
|
android:hour android:minute |
TimePickerBindingAdapter
|
Risorse aggiuntive
Per scoprire di più sull'associazione di dati, consulta le seguenti risorse aggiuntive.
Samples
Codelab
Post del blog
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Utilizzare gli oggetti di dati osservabili
- Layout ed espressioni di associazione
- Associare le viste del layout ai componenti dell'architettura