¡Atención! Este sitio utiliza cookies.
Si no cambias la configuración de tu navegador, aceptas su uso.

Qué es el ‘Inflater’ de Android. Instanciando layouts.

Siempre solemos tratar las vistas de nuestras apps como entidades planas, similares a hojas de periódico que se desplazan sobre rodillos que giran, cabezales que dibujan letra e imágenes… Y realmente es lo que son, objetos planos y pasivos que suponen la corteza de una lógica más compleja que opera por debajo. Sin embargo, en Android las ‘inflamos’. Sí, has leído bien: el androide verde infla/hincha todos los layouts en tiempo de ejecución, y por eso, si es quieres añadir dinámicamente alguno, lo tienes que inflar tú mismo. Y no, no es que Java nos aumente el espacio pulmonar precisamente… eso de ‘inflar’ es algo bien distinto.

Android Inflaters

Al igual que el chaleco salvavidas, “hínchese” antes de usar.

¿Y entonces qué narices es eso de “hinchar”?, te preguntarás.

Realizar un ‘inflate’ en Android es instanciar un xml para poder añadirlo a una jerarquía de vistas.

Y con esa descripción yo me quedaría más ancho que largo. ¿Habéis hecho alguna vez un addSubview en UIKit? Este sería en Android el proceso paralelo si queremos calzar un layout/XML dentro de otro.

El código que muestro a continuación puede servir perfectamente para ilustrar el proceso de “hinchado” completo de cualquier recurso compilado. Y sí, soy un desarrollador de Cocoa, dejad la firma del método tranquila. Soy feliz así.

El LayoutInflater es un servicio propio de Android que nos facilita el mecanismo de “inflado” de los XML, algo así como un hinchador de playa (uno de esos automáticos que imagino que existen pero que nunca he tenido). Podemos recibir uno estándar a partir del contexto (que en el fondo puede representar cualquier Activity).

Inflador de playa

Todos hemos tenido uno de estos

Si ya tenemos el hinchador de playa ya solo nos queda colocar la boquilla en el hinchable en cuestión, colocarlo bien en el suelo, y apretar el botón; es decir, darle el identificador del recurso y la vista padre donde se va a tener que introducir. También podemos indicarle que no lo enganche todavía a esta última, porque no hace falta generalmente. Y es que cuando se ejecuta un inflate no tiene porque —necesariamente— añadirse la nueva vista al resto: son dos procesos separados.

Existe algo de discusión sobre si es necesario o no facilitar una vista padre –como yo la llamo–, o pasar null. A título personal —y con una experiencia más bien justita en la plataforma, eso sí—, en raras ocasiones he podido pasar un nulo sin tener que lidiar con bugs después. Yo recomiendo ponerlo. Si no lo haces, lo más probable es que alguien te diga eso de “You are doin’ it wrong bla bla bla“. Mi opinión es que, como no tengo ni idea de dónde ni cómo va a calzar la vista el sistema, mejor dejo el traje de Batman en el armario y le dejo a él que se busque las habichuelas.

Por razones de rendimiento, este método solo funciona con XML ya compilados. No es capaz de instanciar un documento parseado a partir de texto plano. Molaría mucho, pero no, despídete de recibir layouts desde una API remota.

Ejemplo de una implementación sencilla

Este sería el XML compilado (menu_cell_layout.xml) que queremos cargar:

Y este el código que lo instancia:

La vista resultante ya puede ser introducida en la jerarquía de vistas. Internamente, lo que ha hecho Android ha sido extender el XML padre con el otro, el de la celda (menu_cell_layout.xml), dentro, como si siempre hubiese estado ahí.

Un ‘snippet’ sencillo

Es un proceso tan habitual que por supuesto hay distintas formas de implementarlo, según desde dónde se lleve a cabo. Por ejemplo, esta sería más habitual si estuviéramos dentro de una actividad (en este caso this ya sería el contexto por representar la Activity).

Ejemplo de uso de ‘Inflater’ con un ‘Adapter’

Este es un ejemplo trivial de implementación de un ‘Adapter’.

manual_mujeres

Lo que cualquiera de nosotros desearía: un WomanAdapter

Un ‘Adapter’ no es más que un simple patrón de diseño que ayuda a una clase a comunicarse con otra de naturaleza diferente. En este caso, utilizamos este ItemsAdapter para transformar un array de objetos de tipo Item a celdas para poblar un Grid. Como extendemos de BaseAdapter, se nos proporciona un método que nos pide una vista dada una posición, una vista reusable y su vista contenedora. De este modo, usamos el Inflater para ir a por un xml, hincharlo y utilizar sus componentes (Labels, ImageViews, etc) para asignarles los valores del array.

¿Algún desarrollador iOS en la sala? ¿Te suena el cellForRowAtIndexPath?… Es algo similar. La principal diferencia es que aquí el flujo de información es: NuestroControlador > UnAdapter > LayoutQueHaceDeCelda; y en cambio, en UIKit sería más bien: ControladorDeTabla > (delega en) NuestroControlador > NuestroObjetoCelda.

Yo lo llamo el “Sistema Subway™”: “tú dime cómo lo quieres, que se supone que yo voy a saber hacerlo más rápido y eficientemente”.

subway_datasource

Y con esto y un bizcocho…

Correcciones o preguntas, en los comentarios.

¡Muchas gracias!

Escrito por Miguel Hernández Jaso

Autor del blog. Desarrollador especializado en iOS.

6 respuestas a “Qué es el ‘Inflater’ de Android. Instanciando layouts.”

  1. Tu articulo esta genial, pero sigo sin entender una m*****.
    La proxima vez intenta, nose, suponer por ejemplo que no todo el mundo es desarrollador de Cocoa.
    Lo suyo seria haber puesto una ocmparativa entre findViewById y el inflate ese.

  2. Hola, gracias por las explicaciones.
    Una pregunta:
    tengo dos versiones XML de un cuadro de diálogo, porque uso dos resoluciones (layout y layout-sw600dp).
    ¿Cómo puedo decidir qué layout tengo que “inflar”, en función del dispositivo que ejecuta el apk?

    Cuando trabajamos con setContentView(R.layout.mylayout);
    realmente Android decide qué layout corresponde a la resolución del dispositivo, de forma automática.
    Sin embargo, cuando inflo un xml, tengo que ser yo el que decida cuál es el adecuado a mi dispositivo.

    ¿Hay una forma de hacer esto de forma más transparente al desarrollador?

    gracias,

  3. Hola Miguel!. Muchas gracias por el artículo, me animo de a decir que me resultó esclarecedor. Pero como Albert decía que “uno entiende algo cuando es capaz de explicarlo con sus propias palabras”, querría dejarte mi definición con mis propias palabras para que si puedes las evalúes y me digas si es correcta.

    Inflar significa modificar o adaptar el diseño de un layout según los parámetros de diseño de otro layout (el padre). Luego, ese diseño modificado se puede adjuntar, o no. Como resultado obtendremos un objeto View, el cual podremos manipular.

    Si está bien, quería de paso hacerte otra pregunta. ¿Importa el context que le pasemos?. Quiero decir, en general le vamos a pasar el context del activity en donde estemos trabajando, pero es una duda más bien teórica.

    Saludos y muchas gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Mi Gobierno me obliga a decirle que utilizo 'cookies' en mi página. Si continúa navegando, quiere decir que está conforme con ello.