La mayoría de los desarrolladores de Android probablemente estén familiarizados con elfindViewById()método clásico. Pásele un ID de una de las vistas en su diseño XML y devolverá una referencia a la versión inflada de esa vista. Sin embargo, todo esto suponiendo que haya pasado el ID correcto y que la vista realmente exista.findViewById()no tiene controles integrados para evitar que intente recuperar una vista que no puede recuperar. Ingrese el enlace de vista.

En lugar de utilizarlofindViewById()en cada vista que desee, View Binding genera automáticamente una clase de enlace para cada XML de diseño. Cada vista con un ID se agrega automáticamente a la clase, por lo que puede hacer referencia a ellas directamente.

Agregar enlace de vista a un proyecto Gradle de Android es muy sencillo.

Configuración de Gradle

La vinculación de vistas está habilitada en el nivel de módulo en Gradle. Si tienes varios módulos, tendrás que habilitarla individualmente para cada uno.

En elandroidbloque de nivel de módulobuild.gradle, agregue la opción para habilitar el enlace de vista.

android {
    ...

    buildFeatures {
        viewBindingtrue
    }
}

Puede haber una advertencia sobre acceso ilegal, pero se trata de un error de pelusa y se puede ignorar sin problemas.

Sincroniza el proyecto y se habilitará la vinculación de vistas. Es así de fácil.

Uso de la vinculación de vistas

Hay algunas formas de utilizar View Binding, pero antes de que suceda nada de eso, hablemos sobre cómo se generan las clases de enlace.

Sintaxis del nombre de clase

Digamos que tienes un XML de diseño llamadosome_layout.xml. Su clase de enlace correspondiente se llamaráSomeLayoutBinding. Ese patrón se aplica a todos los archivos.

Cada palabra (separada por guiones bajos en el nombre del archivo) se escribirá en mayúsculas y se eliminarán los guiones bajos. Luego se agregará la palabra "encuadernación" al final.

Creación de instancias con una vista existente

Si ya ha inflado el archivo de diseño y tiene una referencia a la raíz del diseño, puede indicarle a la clase de enlace de Vista que use el diseño existente.

Kotlin:

val binding = SomeLayoutBinding.bind(someLayoutRoot/* should be a View instance */)

Java:

SomeLayoutBinding binding = SomeLayoutBinding.bind(someLayoutRoot/* should be a View instance */);

Por ejemplo, si quisieras usar la clase de enlace en un Fragmento, se vería así.

Kotlin:

class SomeFragment:Fragment(R.layout.some_layout) {
   //Lazy initialization means bind() won't be called until "binding" is referenced.
   privateval binding by lazy { SomeLayoutBinding.bind(view) }

   override funonViewCreated(view: View, savedInstanceState: Bundle?) {
       super.onViewCreated(view, savedInstanceState)
        
       //Once this method is called, you can start using the binding.
    }
}

Java:

public class SomeFragment extends Fragment {
   privateSomeLayoutBinding binding =null;

   public SomeFragment() {
       super(R.layout.some_layout);
    }

   @Override
   public void onViewCreated(View view, Bundle savedInstanceState) {
       super.onViewCreated(view, savedInstanceState);
   
       //Initialize the binding.
        binding = SomeLayoutBinding.bind(view);
    }
}

Creación de instancias con nueva vista

La clase de enlace también puede encargarse de inflar el diseño por usted.

Kotlin:

val binding = SomeLayoutBinding.inflate(layoutInflater/* should be a LayoutInflater instance */)

Java:

SomeLayoutBinding binding = SomeLayoutBinding.inflate(layoutInflater/* should be a LayoutInflater instance */);

Este método es útil tanto en fragmentos como en actividades.

Unejemplo de fragmentose vería así:

Kotlin:

class SomeFragment:Fragment() {
   privateval binding by lazy { SomeLayoutBinding.inflate(LayoutInflater.from(requireContext())) }

   override funonCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) {
       //The "root" of the binding class is the root of its layout.
       returnbinding.root
    }
}

Java:

public class SomeFragment extends Fragment {
   privateSomeLayoutBinding binding =null;

   @Override
   public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       //Initialize the binding.
        binding = SomeLayoutBinding.inflate(inflater);
       //The "getRoot()" method of the binding class returns the root of the layout.
       returnbinding.getRoot();
    }
}

Unejemplo de actividadpodría verse así:

Kotlin:

class SomeActivity:AppCompatActivity() {
   privateval binding by lazy { SomeLayoutBinding.inflate(layoutInflater) }

   override funonCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)

       //This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
       setContentView(binding.root)
    }
}

Java:

public class SomeActivity extends AppCompatActivity {
   privateSomeLayoutBinding binding =null;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       //Instantiate the binding.
        binding = SomeLayoutBinding.inflate(getLayoutInflater());
       //This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
       setContentView(binding.getRoot());
    }
}

Referencias de vistas

Ahora que la clase de enlace de Vista está configurada y lista para usar, es momento de usarla realmente.

Digamos que el contenidosome_layout.xmles algo como lo siguiente:

<LinearLayout
    android:
    ...>
    <FrameLayout
        android:
        ...
        />
    <ImageView
        android:
        ...
        />
    <LinearLayout
        android:
        ...>
        <ImageView
            android:
            ...
            />
   </LinearLayout>
</LinearLayout>

Hay muchos identificadores a los que hacer referencia en el código, pero siempre que tenga la clase de enlace instanciada, hacer referencia será fácil.

En Kotlin, las vistas se referencian mediante variables que coinciden con sus identificadores, con algunos cambios. Se eliminan los guiones bajos y la cadena resultante se convierte en mayúsculas y minúsculas. Por ejemplo, para hacer referenciasome_frame_layoutdesde el código, usaríasbinding.someFrameLayout. LasomeFrameLayoutvariable será una instancia de FrameLayout.

val someFrameLayout: FrameLayout = binding.someFrameLayout

En Java, las vistas se referencian mediante métodos getter que coinciden con sus identificadores, con un formato similar al de Kotlin. Por ejemplo, para hacer referencia asome_frame_layout, utilizaríasbinding.getSomeFrameLayout(). El método devolverá una instancia de FrameLayout.

FrameLayout someFrameLayout = binding.getSomeFrameLayout();

Las referencias de vista también se aplanan en el enlace. Hacer referenciainner_imageviewes lo mismo que hacer referencia asome_frame_layout.

Conclusión

Como seguramente podrás ver, View Binding en Android es fácil de implementar y de usar. En muchos casos, es más fácil de usar quefindViewById().

Para obtener más detalles sobre la implementación de View Binding, junto con algunos ejemplos,consulte la documentación oficial de Google.