Vinculación de vistas Parte de Android Jetpack.
La vinculación de vista es una función que facilita la escritura de código que interactúa con vistas. Una vez que la vinculación de vista está habilitada en un módulo, este genera una vinculación class para cada archivo de diseño XML presente en ese módulo. Una instancia de una vinculación contiene referencias directas a todas las vistas que tienen un ID en el el diseño correspondiente.
En la mayoría de los casos, la vinculación de vistas reemplaza a findViewById
.
Configuración
La vinculación de vistas se habilita módulo por módulo. Para habilitar la vinculación de vistas
establece la opción de compilación viewBinding
en true
en el nivel del módulo
build.gradle
, como se muestra en el siguiente ejemplo:
Groovy
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
Si deseas que se ignore un archivo de diseño mientras se generan clases de vinculación, agrega
El atributo tools:viewBindingIgnore="true"
en la vista raíz de ese diseño
archivo:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
Uso
Si la vinculación de vista está habilitada en un módulo, se genera una clase de vinculación para cada Archivo de diseño XML que contiene el módulo. Cada clase de vinculación contiene referencias a la vista raíz y a todas las vistas que tengan un ID. El nombre de la clase de vinculación es se genera convirtiendo el nombre del archivo XML a mayúscula inicial (pascal case) y agregando el palabra "Vinculación" hasta el final.
Por ejemplo, considera un archivo de diseño llamado result_profile.xml
que contenga
lo siguiente:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
La clase de vinculación generada se llama ResultProfileBinding
. Esta clase tiene dos
campos: un TextView
llamado name
y un Button
llamado button
. El
ImageView
del diseño no tiene un ID, por lo que no se hace referencia a él en el
Binding.
Cada clase de vinculación también incluye un método getRoot()
, que proporciona un
referencia para la vista raíz del archivo de diseño correspondiente. En este ejemplo,
el método getRoot()
de la clase ResultProfileBinding
muestra el
Vista raíz de LinearLayout
.
Las siguientes secciones demuestran el uso de clases de vinculación generadas en actividades y fragmentos.
Cómo usar la vinculación de vista en actividades
Si deseas configurar una instancia de la clase de vinculación para usarla con una actividad, realiza la
siguiendo los pasos de la sección
Método onCreate()
:
- Llama al método
inflate()
estático incluido en la clase de vinculación generada. Esto crea una instancia de la clase de vinculación para la actividad que se usará. - Obtén una referencia a la vista raíz llamando al método
getRoot()
o con la propiedad Kotlin sintaxis. - Pasa la vista raíz a
setContentView()
para convertirlo en la vista activa de la pantalla.
Estos pasos se muestran en el siguiente ejemplo:
Kotlin
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
Java
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
Ahora puedes usar la instancia de la clase de vinculación para hacer referencia a cualquiera de las vistas:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
Cómo usar la vinculación de vista en fragmentos
Si deseas configurar una instancia de la clase de vinculación para usarla con un fragmento, realiza la
los siguientes pasos en la interfaz
onCreateView()
método:
- Llama al método
inflate()
estático incluido en la clase de vinculación generada. Esto crea una instancia de la clase de vinculación para que la use el fragmento. - Obtén una referencia a la vista raíz llamando al método
getRoot()
o con la propiedad Kotlin sintaxis. - Muestra la vista raíz del método
onCreateView()
para que sea la Vista activa en la pantalla.
Kotlin
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
Java
private ResultProfileBinding binding; @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = ResultProfileBinding.inflate(inflater, container, false); View view = binding.getRoot(); return view; } @Override public void onDestroyView() { super.onDestroyView(); binding = null; }
Ahora puedes usar la instancia de la clase de vinculación para hacer referencia a cualquiera de las vistas:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
Proporciona sugerencias para diferentes parámetros de configuración
Cuando declaras vistas en múltiples configuraciones, a veces hace que sentido usar un tipo de vista diferente según el diseño en particular. En el siguiente fragmento de código, se muestra un ejemplo de esto:
# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />
En este caso, es posible que la clase generada exponga un campo userBio
.
de tipo TextView
, porque TextView
es la clase base común. Debido a
técnicas, el generador de código de vinculación de vista no puede determinar esto y
genera un campo View
en su lugar. Esto requiere transmitir el campo más adelante con
binding.userBio as TextView
Para evitar esta limitación, la vinculación de vista admite un tools:viewBindingType
.
lo que te permite indicarle al compilador qué tipo usar en el código generado.
En el ejemplo anterior, puedes usar este atributo para hacer que el compilador
Genera el campo como un TextView
:
# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />
En otro ejemplo, supongamos que tienes dos diseños, uno que contiene una
BottomNavigationView
y otro que contiene un NavigationRailView
. Ambas opciones
extienden NavigationBarView
, que contiene la mayor parte de la implementación
más detalles. Si tu código no necesita saber exactamente qué subclase está presente en
el diseño actual, puedes usar tools:viewBindingType
para configurar la
Escribe en NavigationBarView
en ambos diseños:
# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
La vinculación de vista no puede validar el valor de este atributo cuando se genera código. Para evitar errores de tiempo de ejecución y compilación, el valor debe cumplir con los siguientes condiciones:
- El valor debe ser una clase que se herede de
android.view.View
. El valor debe ser una superclase de la etiqueta en la que se coloca. Por ejemplo, el los siguientes valores no funcionan:
<TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. --> <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
El tipo final debe resolverse de manera coherente en todos los parámetros de configuración.
Diferencias de findViewById
La vinculación de vistas tiene ventajas importantes frente al uso de findViewById
:
- Seguridad nula: dado que la vinculación de vistas crea referencias directas a las vistas
no hay riesgo de una excepción de puntero nulo debido a un ID de vista no válido.
Además, cuando una vista solo está presente en algunas configuraciones de una
diseño, el campo que contiene su referencia en la clase de vinculación se marca
con
@Nullable
. - Seguridad de tipos: los campos de cada clase de vinculación tienen tipos que coinciden con vistas a las que hacen referencia en el archivo en formato XML. Esto significa que no hay riesgo de que una clase transmisión.
Estas diferencias significan incompatibilidades entre tu diseño y tu código. provocaría que tu compilación falle en el tiempo de compilación y no en el tiempo de ejecución.
Comparación con la vinculación de datos
La vinculación de vista y la vinculación de datos generan que puedes usar para hacer referencia a vistas directamente. Sin embargo, la vista está diseñada para manejar casos de uso más simples y proporciona lo siguiente: beneficios en comparación con la vinculación de datos:
- Compilación más rápida: La vinculación de vistas no requiere procesamiento de anotaciones. los tiempos de compilación son más rápidos.
- Facilidad de uso: La vinculación de vista no requiere un diseño XML etiquetado especialmente. por lo que la adopción en tus apps es más rápida. Cuando habilites la vinculación de vistas un módulo, se aplica automáticamente a todos los diseños de ese módulo.
Por otro lado, la vinculación de vista tiene las siguientes limitaciones en comparación con los datos vinculación:
- La vinculación de vista no admite variables ni de diseño con expresiones regulares, por lo que no se puede usar para declarar contenido dinámico de IU directamente desde archivos de diseño XML.
- La vinculación de vista no admite datos bidireccionales vinculación.
Debido a estas consideraciones, en algunos casos es mejor usar ambas y la vinculación de datos en un proyecto. Puedes usar la vinculación de datos en diseños que requieren funciones avanzadas y usan la vinculación de vistas en diseños que no las necesitan.
Recursos adicionales
Si deseas obtener más información sobre la vinculación de vista, consulta los siguientes recursos adicionales:
Ejemplos
Blogs
Videos
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo migrar de sintéticos de Kotlin a vinculación de vistas de Jetpack
- Diseños y expresiones vinculantes
- Arquitectura de la app: Capa de la IU. Cómo comenzar - Android Developers