La libreria Data Binding genera classi di associazione che puoi utilizzare per accedere alle variabili e alle viste del layout. Questa documentazione mostra come creare e personalizzare le classi di associazione generate.
La classe di associazione generata collega le variabili di layout alle viste all'interno del layout. Puoi personalizzare il nome e il pacchetto dell'associazione. Tutte le classi di associazione generate ereditano dalla classe ViewDataBinding
.
Per ogni file di layout viene generata una classe di associazione. Per impostazione predefinita, il nome della classe è il nome del file di layout convertito in maiuscole/minuscole Pascal a cui è stato aggiunto il suffisso Binding. Quindi, ad esempio, se il nome file del layout è activity_main.xml
, la classe generata corrispondente è ActivityMainBinding
.
Questa classe contiene tutte le associazioni dalle proprietà del layout alle viste del layout e sa come assegnare valori per le espressioni di associazione.
Crea un oggetto di associazione
L'oggetto di associazione viene creato immediatamente dopo l'aumento delle dimensioni del layout per garantire che la gerarchia delle viste non venga modificata prima dell'associazione alle viste con espressioni all'interno del layout. Il metodo più comune per associare l'oggetto a un layout è utilizzare i metodi statici nella classe di associazione. Puoi gonfiare la gerarchia delle visualizzazioni e associare l'oggetto utilizzando il metodo inflate()
della classe di associazione, come mostrato nell'esempio seguente:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
Esiste una versione alternativa del metodo inflate()
che accetta un oggetto ViewGroup
oltre all'oggetto LayoutInflater
, come mostrato nell'esempio seguente:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Se il layout viene gonfiato utilizzando un meccanismo diverso, puoi associarlo separatamente, come segue:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
A volte non conosci il tipo di associazione in anticipo. In questi casi, puoi creare l'associazione utilizzando la classe DataBindingUtil
, come illustrato nel seguente snippet di codice:
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Se utilizzi elementi di associazione di dati all'interno di un adattatore Fragment
, ListView
o RecyclerView
, ti consigliamo di utilizzare i metodi inflate()
delle classi di associazioni o la classe DataBindingUtil
, come mostrato nell'esempio di codice riportato di seguito:
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Viste con ID
La libreria di associazione dei dati crea un campo immutabile nella classe di associazione per ogni vista che ha un ID nel layout. Ad esempio, la libreria di associazione dati crea i campi firstName
e lastName
di tipo TextView
dal seguente layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
La libreria estrae le viste, inclusi gli ID, dalla gerarchia delle visualizzazioni in un unico passaggio. Questo meccanismo può essere più veloce rispetto alla chiamata del metodo findViewById()
per ogni visualizzazione del layout.
Gli ID non sono necessari in quanto senza associazione di dati, ma ci sono ancora alcune istanze in cui l'accesso alle viste è necessario dal codice.
Variabili
La libreria Data Binding genera metodi della funzione di accesso per ogni variabile dichiarata nel layout. Ad esempio, il seguente layout genera metodi setter e getter nella classe di associazione per le variabili user
, image
e note
:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
Stub di visualizzazione
Diversamente dalle viste normali, gli oggetti ViewStub
iniziano come viste invisibili. Quando vengono rese visibili o gonfiate in modo esplicito,
si sostituiscono nel layout gonfiando un altro layout.
Poiché ViewStub
scompare dalla gerarchia delle visualizzazioni, anche la visualizzazione nell'oggetto di associazione deve scomparire per poter essere rivendicata dalla garbage collection.
Poiché le viste sono definitive, un oggetto ViewStubProxy
sostituisce ViewStub
nella classe di associazione generata, concedendoti l'accesso a ViewStub
quando esiste e l'accesso alla gerarchia di visualizzazioni ingrandita quando ViewStub
viene aumentato in modo artificioso.
Quando si gonfia un altro layout, è necessario che il nuovo layout venga associato a un'associazione.
Di conseguenza, l'elemento ViewStubProxy
deve ascoltare l'elemento ViewStub
OnInflateListener
e stabilire l'associazione quando richiesto. Poiché può esistere un solo listener alla volta, ViewStubProxy
consente di impostare un OnInflateListener
, che chiama dopo aver stabilito l'associazione.
Associazione immediata
Quando una variabile o un oggetto osservabile cambia, l'associazione è pianificata per cambiare prima del frame successivo. Tuttavia, a volte l'associazione deve essere eseguita
immediatamente. Per forzare l'esecuzione, utilizza il metodo executePendingBindings()
.
Variabili dinamiche
A volte, la classe di associazione specifica è sconosciuta. Ad esempio, un elemento RecyclerView.Adapter
che utilizza layout arbitrari non conosce la classe di associazione specifica. Deve
assegnare il valore di associazione durante la chiamata al
metodo onBindViewHolder()
.
Nell'esempio seguente, tutti i layout associati da RecyclerView
hanno una variabile item
. L'oggetto BindingHolder
ha un metodo getBinding()
che restituisce la classe base ViewDataBinding
.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
Thread in background
Puoi modificare il modello dei dati in un thread in background purché non si tratti di una raccolta. L'associazione di dati localizza ogni variabile o campo durante la valutazione, per evitare problemi di contemporaneità.
Nomi delle classi di associazioni personalizzate
Per impostazione predefinita, una classe di associazione viene generata in base al nome del file di layout, iniziando con una lettera maiuscola, rimuovendo i trattini bassi ( _ ), utilizzando le lettere maiuscole per la lettera successiva e il suffisso Binding. Ad esempio, il file di layout contact_item.xml
genera la classe ContactItemBinding
. La classe si trova
in un pacchetto databinding
sotto il pacchetto del modulo. Ad esempio, se il pacchetto di moduli è com.example.my.app
, la classe di associazione viene inserita nel pacchetto com.example.my.app.databinding
.
Le classi di associazione possono essere rinominate o inserite in pacchetti diversi regolando l'attributo class
dell'elemento data
. Ad esempio, il seguente layout genera la classe di associazione ContactItem
nel pacchetto databinding
del modulo corrente:
<data class="ContactItem">
...
</data>
Puoi generare la classe di associazione in un altro pacchetto anteponendo al nome della classe un punto. L'esempio seguente genera la classe di associazione nel pacchetto del modulo:
<data class=".ContactItem">
...
</data>
Puoi anche utilizzare il nome completo del pacchetto in cui vuoi generare la classe di associazione. L'esempio seguente crea la classe di associazione ContactItem
nel
pacchetto com.example
:
<data class="com.example.ContactItem">
...
</data>
Risorse aggiuntive
Per saperne di più sull'associazione di dati, consulta le risorse aggiuntive riportate di seguito.
- Esempi di libreria di Data Binding per Android
- Associazione dati in Android
- Associazione di dati: lezioni apprese
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Layout ed espressioni di associazione
- Libreria di associazioni dati
- Visualizza associazione