Los dispositivos Android vienen de todas las formas y tamaños, por lo que el diseño de tu app debe ser flexible. Es decir que, en lugar de definir un diseño con dimensiones rígidas para un tamaño de pantalla y una relación de aspecto determinados, tu diseño debería ajustarse a pantallas de diferentes tamaños y orientaciones.
La compatibilidad con muchas pantallas permite que la app se encuentre disponible para la mayor cantidad posible de usuarios con dispositivos diferentes, mediante un único APK. Además, hacer que tu app funcione en distintos tamaños de pantalla garantiza poder procesar cambios en la configuración de la ventana del dispositivo, como cuando el usuario habilita el modo multiventana.
En esta página, se muestra cómo lograr la compatibilidad con distintos tamaños de pantalla mediante las siguientes técnicas:
- Usa dimensiones de vista que permitan cambiar el tamaño del diseño.
- Crea diseños de IU alternativos en función de la configuración de la pantalla.
- Proporciona mapas de bits que puedan expandir las vistas.
Sin embargo, debes tener en cuenta que adaptar tu app a diferentes tamaños de pantalla no necesariamente hace que sea compatible con todos los factores de forma de Android. Deberás realizar pasos adicionales para agregar compatibilidad con dispositivos Android Wear, Android TV, Android Auto y el Sistema operativo Chrome.
Si quieres conocer las pautas de diseño a fin de compilar IU para diferentes pantallas, consulta los lineamientos sobre el material de IU reactiva.
Cómo crear un diseño flexible
Independientemente del perfil de hardware con el que quieras brindar compatibilidad primero, debes crear un diseño que sea receptivo incluso para las variaciones más leves de tamaño de pantalla.
Cómo usar ConstraintLayout
La mejor manera de crear un diseño reactivo para diferentes tamaños de pantalla es usar ConstraintLayout
como el diseño base en tu IU. ConstraintLayout
te permite especificar la posición y el tamaño de cada vista según las relaciones espaciales con otras vistas en el diseño. De esta manera, todas las vistas pueden moverse y expandirse a la vez, a medida que cambia el tamaño de la pantalla.
La forma más fácil de compilar un diseño con ConstraintLayout
es usar el editor de diseño de Android Studio, ya que te permite arrastrar nuevas vistas al diseño, asociar sus restricciones a la vista principal y a otras vistas relacionadas, y editar las propiedades de la vista, todo sin la necesidad de editar ningún archivo XML manualmente (ver figura 1).
Para obtener más información, consulta Cómo crear una IU reactiva con ConstraintLayout.
Figura 1: El editor de diseño en Android Studio muestra un archivo ConstraintLayout
Aunque ConstraintLayout
no resolverá todas las situaciones de diseño (especialmente en el caso de las listas cargadas de forma dinámica, donde deberás usar RecyclerView), no importa cuál sea el diseño que utilices, siempre debes evitar los tamaños de diseño hard-coded (consulta la siguiente sección).
Cómo evitar usar tamaños de diseño hard-coded
Para asegurarte de que tu diseño sea flexible y se adapte a diferentes tamaños de pantalla, debes usar "wrap_content"
y "match_parent"
para el ancho y la altura de la mayoría de los componentes de la vista, en lugar de los tamaños hard-coded.
"wrap_content"
le indica a la vista que establezca el tamaño necesario para ajustar el contenido dentro de esa vista.
"match_parent"
hace que la vista se expanda lo más posible dentro de la vista principal.
Por ejemplo:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum" />
Aunque el diseño real de esta vista depende de otros atributos en su vista principal y cualquier vista relacionada, esta TextView
intenta establecer el ancho para rellenar todo el espacio disponible (match_parent
) y configurar la altura para que sea exactamente igual al espacio requerido para la longitud del texto (wrap_content
). Esto permite que la vista se adapte a diferentes tamaños de pantalla y diferentes longitudes de texto.
La figura 2 muestra cómo se ajusta el ancho de la vista de texto con "match_parent"
a medida que cambia el ancho de la pantalla con la orientación del dispositivo.
Figura 2: Vista de texto flexible
Si usas un LinearLayout
, también puedes expandir las vistas secundarias con ponderación de diseño para que cada vista rellene el espacio restante proporcionalmente a su valor de ponderación. Sin embargo, el uso de ponderaciones en un LinearLayout
anidado requiere que el sistema realice varios pases de diseño para determinar el tamaño de cada vista, lo que ralentiza el rendimiento de la IU.
Afortunadamente, ConstraintLayout
puede lograr casi todos los diseños posibles con LinearLayout
sin afectar el rendimiento, por lo que debes intentar convertir tu diseño a ConstraintLayout. Luego, puedes definir los diseños ponderados mediante cadenas de restricciones.
Cómo crear diseños alternativos
Si bien el diseño siempre debe responder a diferentes tamaños de pantalla, ampliando el espacio entre las vistas y alrededor de estas, es posible que no brinde la mejor experiencia del usuario para todos los tamaños de pantalla. Por ejemplo, la IU que diseñaste para un teléfono probablemente no brinde una buena experiencia en una tablet. Por lo tanto, también debes proporcionar recursos de diseño alternativos a fin de optimizar el diseño de la IU para determinados tamaños de pantalla.
Figura 3: La misma app en pantallas de distintos tamaños usa un diseño diferente para cada una
Puedes proporcionar diseños específicos de la pantalla mediante la creación de directorios res/layout/
adicionales (uno para cada configuración de pantalla que requiera un diseño diferente) y, luego, agregar un calificador de configuración de pantalla al nombre del directorio layout
(como layout-w600dp
para pantallas que tengan 600 dp de ancho disponible).
Esos calificadores de configuración representan el espacio de pantalla visible disponible para la IU de tu app. El sistema considera cualquier decoración (como la barra de navegación) y cambio en la configuración de la ventana (como cuando el usuario habilita el modo multiventana) al seleccionar el diseño desde la app.
Para crear un diseño alternativo en Android Studio (con la versión 3.0 o posterior) haz lo siguiente:
- Abre tu diseño predeterminado y, luego, haz clic en Orientation for Preview
, en la barra de herramientas.
- En la lista desplegable, haz clic para crear una variante sugerida, como Create Landscape Variant, o haz clic en Create Other.
- Si eliges Create Other, aparecerá la opción Select Resource Directory. Aquí, deberás seleccionar un calificador de pantalla del lado izquierdo y agregarlo a la lista de Chosen qualifiers. Cuando termines de agregar calificadores, haz clic en OK. (Consulta las siguientes secciones para obtener información sobre los calificadores de tamaños de pantalla).
De esta manera, se crea un archivo de diseño duplicado en el directorio de diseño correspondiente, para que puedas empezar a personalizar el diseño de esa variante de pantalla.
Cómo usar el calificador de ancho mínimo
El calificador de tamaño de pantalla de "ancho mínimo" te permite proporcionar diseños alternativos para pantallas que tienen un ancho mínimo medido en píxeles independientes de la densidad (dp o dip).
La descripción de Android del tamaño de la pantalla como una medida de píxeles independientes de la densidad te permite crear diseños para dimensiones de pantalla muy específicas y evitar cualquier preocupación que tengas respecto de las diferentes densidades de píxeles.
Por ejemplo, puedes crear un diseño llamado main_activity
que esté optimizado para teléfonos celulares y tablets creando diferentes versiones del archivo en los directorios de la siguiente manera:
res/layout/main_activity.xml # For handsets (smaller than 600dp available width) res/layout-sw600dp/main_activity.xml # For 7” tablets (600dp wide and bigger)
El calificador de ancho mínimo especifica el lado más pequeño de la pantalla, independientemente de la orientación actual del dispositivo, por lo que es una manera sencilla de especificar el tamaño de pantalla total disponible para tu diseño.
A continuación, se muestra cómo los valores de ancho mínimo se corresponden con los tamaños de pantalla típicos:
- 320 dp: una pantalla típica de teléfono (240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi, etc.)
- 480 dp: una pantalla de teléfono grande de ~5" (480 x 800 mdpi)
- 600 dp: una tablet de 7" (600 x 1024 mdpi)
- 720 dp: una tablet de 10" (720 x 1280 mdpi, 800 x 1280 mdpi, etc.)
En la figura 4, se proporciona una vista más detallada de cómo los diferentes anchos de dp de pantalla generalmente se corresponden con los tamaños y las orientaciones de pantalla diferentes.
Figura 4: Interrupciones de ancho recomendadas para admitir diferentes tamaños de pantalla
Recuerda que todas las cifras del calificador de ancho mínimo corresponden a píxeles independientes de la densidad, porque lo que importa es la cantidad de espacio de pantalla disponible luego de que el sistema calcula la densidad de píxeles (no la resolución de píxeles bruta).
Cómo usar el calificador de ancho disponible
En lugar de cambiar el diseño en función del ancho mínimo de la pantalla, puedes cambiar tu diseño según el ancho o la altura disponible actualmente. Por ejemplo, si tienes un diseño de dos paneles, puede que quieras usarlo cada vez que la pantalla proporcione un ancho mínimo de 600 dp, lo que podría variar en función de si el dispositivo se encuentra en orientación horizontal o vertical. En este caso, deberías usar el calificador de "ancho disponible" de la siguiente manera:
res/layout/main_activity.xml # For handsets (smaller than 600dp available width) res/layout-w600dp/main_activity.xml # For 7” tablets or any screen with 600dp # available width (possibly landscape handsets)
Si te preocupa la altura disponible, puedes hacer lo mismo con el calificador de "altura disponible". Por ejemplo, layout-h600dp
para pantallas con al menos 600 dp de altura de pantalla.
Cómo agregar calificadores de orientación
Aunque puedes admitir todas las variaciones de tamaño con solo usar combinaciones de calificadores de "ancho mínimo" y "ancho disponible", es posible que también quieras cambiar la experiencia del usuario cuando este alterne entre las orientaciones vertical y horizontal.
Para eso, puedes agregar los calificadores port
o land
a los nombres del directorio de recursos. Asegúrate de que se ubiquen después de los otros calificadores de tamaño. Por ejemplo:
res/layout/main_activity.xml # For handsets res/layout-land/main_activity.xml # For handsets in landscape res/layout-sw600dp/main_activity.xml # For 7” tablets res/layout-sw600dp-land/main_activity.xml # For 7” tablets in landscape
Para obtener más información sobre todos los calificadores de configuración de la pantalla, consulta la tabla 2 de la guía sobre Cómo proporcionar recursos.
Cómo utilizar el sistema modular para componentes de la IU con fragmentos
Cuando diseñes tu app para varios tamaños de pantalla, asegúrate de no duplicar innecesariamente el comportamiento de la IU en las actividades. Para ello, debes usar fragmentos a fin de extraer la lógica de tu IU en componentes individuales. Luego, podrás combinar los fragmentos para crear diseños de varios paneles cuando ejecutes la app en una pantalla grande o ubicarlos en actividades individuales cuando ejecutes la app en un teléfono celular.
Por ejemplo, una app de noticias en una tablet podría mostrar una lista de artículos en el lado izquierdo y un artículo completo en el lado derecho (al seleccionar un artículo del lado izquierdo, se actualiza la vista del artículo en el lado derecho). Sin embargo, en un teléfono celular, estos dos componentes deben aparecer en pantallas separadas (cuando se elige un artículo de la lista, se cambia toda la pantalla para mostrarlo).
Para obtener más información, consulta Cómo compilar una IU dinámica con fragmentos.
Cómo generar compatibilidad con Android 3.1 mediante calificadores de tamaño heredados
Si tu app admite Android 3.1 (API nivel 12) o versiones anteriores, deberás usar los calificadores de tamaño heredados además de los calificadores de ancho mínimo/disponible descritos anteriormente.
En el ejemplo anterior, si quieres un diseño de dos paneles en dispositivos más grandes, debes usar el calificador de configuración "grande" para que admita la versión 3.1 y versiones anteriores. Por lo tanto, para implementar estos diseños en esas versiones anteriores, es posible que necesites los siguientes archivos:
res/layout/main_activity.xml # For handsets (smaller than 640dp x 480dp) res/layout-large/main_activity.xml # For small tablets (640dp x 480dp and bigger) res/layout-xlarge/main_activity.xml # For large tablets (960dp x 720dp and bigger)
Cómo usar alias de diseño
Para admitir versiones anteriores y posteriores de Android 3.2, deberás usar los calificadores grandes y de ancho mínimo para tus diseños. De esta manera, tendrías un archivo llamado res/layout-large/main.xml
que podría ser idéntico a res/layout-sw600dp/main.xml
.
Para evitar la duplicación del mismo archivo, puedes usar archivos de alias. Por ejemplo, puedes definir los siguientes diseños:
res/layout/main.xml # single-pane layout res/layout/main_twopanes.xml # two-pane layout
Y agregar estos dos archivos:
res/values-large/layout.xml
:<resources> <item name="main" type="layout">@layout/main_twopanes</item> </resources>
res/values-sw600dp/layout.xml
:<resources> <item name="main" type="layout">@layout/main_twopanes</item> </resources>
Estos dos archivos tienen el mismo contenido, pero en realidad no definen el diseño. Solo configuran main
para que sea un alias de main_twopanes
. Dado que esos archivos tienen selectores large
y sw600dp
, se aplican a pantallas grandes, independientemente de la versión de Android (las tablets y TVs con versiones anteriores a 3.2 coinciden con large
, y las versiones posteriores coincidirán con sw600dp
).
Cómo crear mapas de bits expandibles de 9-Patch
Si usas un mapa de bits como fondo en una vista que cambia de tamaño, verás que Android escalará tu imagen a medida que la vista se expanda o se contraiga en función del tamaño de la pantalla o del contenido en la vista, lo que suele provocar imágenes borrosas o algún otro artefacto de escalamiento. La solución es utilizar mapas de bits de 9-Patch, es decir, archivos PNG con formato especial que indican las áreas expandibles y no expandibles.
Un mapa de bits de 9-Patch es básicamente un archivo PNG estándar, pero con un borde adicional de 1 px que indica qué píxeles se deben expandir (y con una extensión .9.png
en lugar de solo .png
). Como se muestra en la figura 5, la intersección entre las líneas negras en el borde izquierdo y superior es el área del mapa de bits que se puede expandir.
También puedes definir una región segura en la que el contenido se ubique dentro de la vista si agregas, de manera similar, líneas en el lado derecho y en el borde inferior.
Figura 5: Una imagen de 9-Patch (button.9.png
)
Cuando aplicas un 9-Patch como fondo de una vista, el framework expande la imagen correctamente para ajustarse al tamaño del botón.
Para obtener información sobre cómo crear una imagen de 9-Patch a partir de un mapa de bits, consulta Cómo crear mapas de bits de tamaño ajustable.
Cómo probar tu app en todos los tamaños de pantalla
Es importante que pruebes tu app en varios tamaños de pantalla para asegurarte de que la IU se escale correctamente. Si no tienes acceso a dispositivos físicos de todos los tamaños de pantalla, puedes usar Android Emulator para emular cualquier tamaño de pantalla.
Si prefieres probarla en dispositivos físicos, pero no quieres comprarlos, puedes usar Firebase Test Lab para acceder a dispositivos en un centro de datos de Google.
Cómo declarar la compatibilidad con tamaños de pantalla específicos
Si no quieres que se ejecute tu app en determinados tamaños de pantalla, puedes establecer límites que especifiquen cuánto puede cambiarse el tamaño de la pantalla o incluso restringir los dispositivos que pueden instalar tu app en función de la configuración de la pantalla. Para obtener más información, consulta Cómo declarar una compatibilidad de pantalla restringida.