Clases de vinculación generadas

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.