La biblioteca de vinculación de datos genera clases de vinculación que puedes usar para acceder a las variables y vistas del diseño. En esta documentación, se muestra cómo crear y personalizar las clases de vinculación generadas.
La clase de vinculación generada vincula las variables de diseño con las vistas dentro del diseño. Puedes personalizar el nombre y el paquete de la vinculación. Todas las clases de vinculación generadas se heredan de la clase ViewDataBinding
.
Para cada archivo de diseño, se genera una clase de vinculación. De forma predeterminada, el nombre de la clase es el nombre del archivo de diseño convertido al formato Pascal con el sufijo Binding. Por ejemplo, si el nombre de archivo de diseño es activity_main.xml
, la clase generada correspondiente es ActivityMainBinding
.
Esta clase contiene todas las vinculaciones, desde las propiedades de diseño hasta las vistas del diseño, y sabe cómo asignar valores para las expresiones de vinculación.
Crea un objeto de vinculación
El objeto de vinculación se crea inmediatamente después de aumentar el diseño para garantizar que la jerarquía de vistas no se modifique antes de vincularse a las vistas con expresiones dentro del diseño. El método más común para vincular el objeto a un diseño es usar los métodos estáticos en la clase de vinculación. Puedes aumentar la jerarquía de vistas y vincular el objeto a ella mediante el método inflate()
de la clase de vinculación, como se muestra en el siguiente ejemplo:
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); }
Existe una versión alternativa del método inflate()
que toma un objeto ViewGroup
además del objeto LayoutInflater
, como se muestra en el siguiente ejemplo:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Si el diseño aumenta con un mecanismo diferente, puedes vincularlo por separado de la siguiente manera:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
A veces, no conoces el tipo de vinculación de antemano. En esos casos, puedes crear la vinculación usando la clase DataBindingUtil
, como se muestra en el siguiente fragmento de código:
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);
Si usas elementos de vinculación de datos dentro de un adaptador Fragment
, ListView
o RecyclerView
, es posible que prefieras usar los métodos inflate()
de las clases de vinculación o la clase DataBindingUtil
, como se muestra en el siguiente ejemplo de código:
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);
Vistas con ID
La biblioteca de vinculación de datos crea un campo inmutable en la clase de vinculación para cada vista que tiene un ID en el diseño. Por ejemplo, la biblioteca de vinculación de datos crea los campos firstName
y lastName
de tipo TextView
del siguiente diseño:
<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 biblioteca extrae las vistas, incluidos los ID, de la jerarquía de vistas en un solo pase. Este mecanismo puede ser más rápido que llamar al método findViewById()
para cada vista del diseño.
Los IDs no son tan necesarios como lo son sin vinculación de datos, pero hay algunas instancias en las que es necesario acceder a las vistas desde el código.
Variables
La biblioteca de vinculación de datos genera métodos de acceso para cada variable declarada en el diseño. Por ejemplo, el siguiente diseño genera métodos set y get en la clase de vinculación para las variables user
, image
y 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>
ViewStubs
A diferencia de las vistas normales, los objetos ViewStub
comienzan como vistas invisibles. Cuando se hacen visibles o se aumentan explícitamente, se reemplazan en el diseño aumentando otro diseño.
Debido a que ViewStub
desaparece de la jerarquía de vistas, la vista en el objeto de vinculación también debe desaparecer para permitir que la recolección de elementos no utilizados la reclame.
Debido a que las vistas son definitivas, un objeto ViewStubProxy
toma el lugar de ViewStub
en la clase de vinculación generada, lo que te brinda acceso a ViewStub
cuando existe y a la jerarquía de vistas aumentada cuando se aumenta ViewStub
.
Cuando se aumenta otro diseño, se debe establecer una vinculación para el diseño nuevo.
Por lo tanto, ViewStubProxy
debe escuchar a ViewStub
OnInflateListener
y establecer la vinculación cuando sea necesario. Dado que solo puede existir un objeto de escucha a la vez, ViewStubProxy
te permite establecer un OnInflateListener
, al que llama después de establecer la vinculación.
Vinculación inmediata
Cuando cambia una variable o un objeto observable, la vinculación está programada para cambiar antes del siguiente fotograma. Sin embargo, hay momentos en los que la vinculación debe ejecutarse de inmediato. Para forzar la ejecución, usa el método executePendingBindings()
.
Variables dinámicas
A veces, se desconoce la clase de vinculación específica. Por ejemplo, un objeto RecyclerView.Adapter
que opera contra diseños arbitrarios no conoce la clase de vinculación específica. Debe asignar el valor de vinculación durante la llamada al método onBindViewHolder()
.
En el siguiente ejemplo, se muestran todos los diseños que la RecyclerView
vincula para tener una variable item
. El objeto BindingHolder
tiene un método getBinding()
que muestra la clase 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(); }
Subproceso en segundo plano
Puedes cambiar tu modelo de datos en un subproceso en segundo plano, siempre y cuando no sea una colección. La vinculación de datos localiza cada variable o campo durante la evaluación para evitar problemas de simultaneidad.
Nombres de clases de vinculación personalizadas
De forma predeterminada, se genera una clase de vinculación basada en el nombre del archivo de diseño. Comienza con una letra mayúscula, se quitan los guiones bajos ( _), se usa mayúscula en la siguiente letra y se usa el sufijo Binding. Por ejemplo, el archivo de diseño contact_item.xml
genera la clase ContactItemBinding
. La clase se coloca en un paquete databinding
debajo del paquete del módulo. Por ejemplo, si el paquete del módulo es com.example.my.app
, la clase de vinculación se coloca en el paquete com.example.my.app.databinding
.
Las clases de vinculación se pueden renombrar o colocar en diferentes paquetes ajustando el atributo class
del elemento data
. Por ejemplo, el siguiente diseño genera la clase de vinculación ContactItem
en el paquete databinding
del módulo actual:
<data class="ContactItem">
...
</data>
Puedes generar la clase de vinculación en un paquete diferente si le antepones un punto al nombre de la clase. En el siguiente ejemplo, se genera la clase de vinculación en el paquete del módulo:
<data class=".ContactItem">
...
</data>
También puedes usar el nombre completo del paquete en el que deseas que se genere la clase de vinculación. En el siguiente ejemplo, se crea la clase de vinculación ContactItem
en el paquete com.example
:
<data class="com.example.ContactItem">
...
</data>
Recursos adicionales
Para obtener más información sobre la vinculación de datos, consulta los siguientes recursos adicionales.
- Ejemplos de la biblioteca de vinculación de datos de Android
- Vinculación de datos en Android
- Vinculación de datos: lecciones aprendidas
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Diseños y expresiones vinculantes
- Biblioteca de vinculación de datos
- Vinculación de vista