Android: soportando multiples pantallas

Un vistazo

  • Android se ejecuta en dispositivos que tienen distintos tamaños de pantalla y distintas densidades
  • La pantalla en la que tu app es mostrada puede tener impacto en el interface de usuario de tu app.
  • El sistema maneja la mayoria del trabajo a la hora de adaptar tu app a la pantalla que sea.
  • Debes crear recursos especificos de pantalla para tener un control preciso de tu UI.

Android se ejecuta en una variedad de dispositivos que ofrecen distintos tamaños de pantallas y densidades. Para aplicaciones, el sistema Android proporciona un entorno de desarrollo consistente entre dispositivos y maneja la mayor parte de trabajo a la hora de ajustar el interfaz de usuario de las apps a la pantalla en la cual es está mostrando. Al mismo tiempo, el sistema proporciona APIs que te permiten controlar el UI de tu app para densidades y tamaños de pantallas especificos, para optimizar el diseño de tu UI para distintas configuraciones de pantallas. Por ejemplo, puedes querer un UI para tablets que es distintos del UI para smartphones.

Aunque el sistema realiza escalado y resizado para que tu app funcione en distintas pantallas, debes hacer un esfuerzo en optimizar tu app para distintos tamaños de pantalla y densidades. Haciendo eso, maximizas la experiencia de usuario para todos los dispositivos y tus usuarios creeran que tu app ha sido diseñada para su dispositivo.

Siguiendo las prácticas descritas en este documento, puedes crear una app que muestra el interfaz correctamente y proporciona una experiencia de usuario optimizada en todas las configuraciones de pantalla , utilizando un solo fichero .apk.

Nota: La información de este documento asume que tu app esta diseñada para Android 1.6 (API Level 4) o superior. Si tu app soporta Android 1.5 o más bajo, primero lee Strategies for Android 1.5.

También, ten en cuenta que Android 3.2 ha introducido nuevos APIs que te permiten controlar más precisamente los recursos de layouts que tu app utiliza para distintos tamaños de pantalla. Estas nuevas características son especialmente importantes si estas programando una app que sea optimizada para tablets. Para más info Declaring Tablet Layouts for Android 3.2.

Un vistazo al Screens Support

Esta sección proporciona un vistazo del soporte de Android para múltiples pantallas, incluyendo una introducción a los términos y conceptos utilizados en este documento y en el API, un resumen de las configuraciones de pantalla que el sistema soporta, y un vistazo del API y de las características de compatibilidad de pantallas que tiene implementados.

Términos y conceptos

Támano de pantalla (Screen size)
El támaño físico de la pantalla, medido como la diagonal de la pantalla (como en los televisores).
Por simplicidad, Android agrupa todos los támaños de pantallas actuales en cuatro tamaños generales: small, normal, large, and extra large.
Densidad de pantalla (Screen density)
La cantidad de píxeles dentro de una área física de la pantalla; normalmente referidos como dpi (dots per inch). Por ejemplo, una densidad de pantalla baja tiene menos pixeles ,dentro de una área dada de la pantalla, comparado con densidades de pantallas normales o altas.
Por simplicidad, Android agrupa todas las densidades de pantallas actuales en cuatro grupos: low, medium, high, and extra high.
Orientación
La orientación de la pantalla desde el punto de vista del usuario. Esto es, landscape o portrait, es decir apaisado o en vertical respectivamente. Que quede claro que además de que los distintos dispositivos pueden operar en una u otra orientación, para un mismo dispositivo la orientación puede cambiar en tiempo de ejecución cuando el usuario rote el dispositivo.
Resolución
El número total de pixeles físicos de una pantalla. Cuando añadimos soporte para múltiples pantallas, las aplicaciones no funcionan directamente con resoluciones; las apps deben solo preocuparse del támaño de pantalla y de la densidad, es decir deben preocuparse de los dos grupos dichos antes (el grupo de tamaños y el grupo de densidades).
Pixel independiente de la densidad –> Density-independent pixel (dp)
Una unidad de pixel virtual que debes utilizar cuando se define un layout, para expresar las dimensiones del layout o las posiciones de los elementos de forma que sea independiente de la densidad.
El pixel independiente de la densidad es equivalente a un pixel físico en una pantalla de 160 dpi, lo cual es la densidad base asumida por el sistema para una pantalla de densidad media. En tiempo de ejecución, el sistema , de forma trnasparente, maneja el escalado de las unidades dp, según sea necesario, basándose en la densidad actual de la pantalla en uso. La conversión de unidades dp a pixeles de pantalla es simple:  px = dp * (dpi / 160).Por ejemplo, en una pantalla de 240 dpi, 1dp es igual a 1.5 píxeles físicos. Debes siempre utilizar unidades dp cuando se defina el UI de la app, para asegurar que las pantallas se muestren propiamente en pantallas con distintas densidades.

Rango de pantallas soportados

Empezando con Android 1.6 (API level 4), Android proporciona soporte para múltiples pantallas y densidades, reflejando las muchas configuraciones que un dispositivo puede tener. Puedes utilizar características del sistema Android para optimizar el interfaz de usuario de tu app para configuraciones de pantalla específicas.

Para simplificar la forma en la que diseñas tus interfaces de usuario para múltiples pantallas, Android divide el rango de tamaños de pantallas actuales y densidades en:

  • Un conjunto de cuatro tamaños generalizados:  smallnormallarge, and xlarge. Nota: Desde Android 3.2 (API Level 13), estos grupos de tamaños están deprecados en favor de nuevas técnicas para manejar tamaños de pantallas basados en la anchura disponible de pantalla. Si estás programando para Android 3.2 o superior , ver  Declaring Tablet Layouts for Android 3.2 .
  • Un conjunto de cuatro densidades generalizadasldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)

Los tamaños y densidades generalizados están definidos sobre una configuración base que es el tamaño normal y la densidad mdpi. Esta configuración base esta basada en la configuración de pantalla del primer dispositivo Android , el T-Mobile G1, que tenia una pantalla HVGA (hasta Android 1.6, esta fue la única configuración de pantalla que Android soportaba).

Cada tamaño y densidad generalizados incluye una rango de tamaños y densidades reales. Por ejemplo, dos dispositivos que ambos informen que tiene un tamaño de pantalla normal pueden tener tamaños de pantalla y aspect ratios que sean ligeramente distintos cuando son medidos a mano. Lo mismo puede pasar con dos dispositivos que informen de tener un densidad mdpi. Android hace que estas diferencias sean transparentes al usuario, de forma que tu solo debes preocuparte para programar tus apps de acuerdo a los tamaños y las densidades generalizados y deja que Android maneje los ajustes finales. La figura 1 ilustra como los tamaños y densidades reales se agrupan en categorias:

Figure 1. Gráfico de cómo Android mapea los tamaños y densidades reales a tamaños y densidades generalizados (el gráfico no es exacto pero se aproxima).

Según diseñes tu UI para distintos tamaños de pantallas, descubrirás que cada diseño requiere una mínima cantidad de espacio. Asi, cada tamaño de pantalla generalizado tiene una resolución mínima asociada que está definida por el sistema. Estos tamaños mínimos están en unidades “dp” – las mismas unidades que debes utilizar en tus layouts – que permiten al sistema no preocuparse por cambios en la densidad de la pantalla.

  • xlarge tiene al menos 960dp x 720dp
  • large tiene al menos 640dp x 480dp
  • normal tiene al menos 470dp x 320dp
  • small tiene al menos 426dp x 320dp

Nota: Estos tamaños de pantalla mínimos fueron definidos antes de Android 3.0, por lo que puede haber algunos dispositivos que esten sin clasificar entre normal y large. Estos tamaños también están basados en la resolución física de la pantalla, que puede variar entre dispositivos. por ejemplo una tablet de 1024×768 que utilice una barra de sistema tiene un poco de menos espacio para la aplicación debido al espacio que ocupa la system bar.

Para optimizar el UI de tu app para los distintos tamaños de pantalla y densidades, puedes añadir recursos alternativos para todos los tamaños y densidades. Tipicamente, se hacen layouts alternativos para algunos tamaños diferentes de pantalla asi como imagenes alternativas para distintas densidades. En tiempo de ejecución, el sistema utiliza los recursos apropiados para tu app, basandose en la densidad y tamaño generalizados que trae la pantalla del dispositivo.

No es necesario añadir recursos alternativos para todas las combinaciones de tamaño y densidad. El sistema proporciona características de compatibilidad robustas que gestiona la mayor parte del trabajo de rendering en todas las pantallas , suponiendo que has implementado tu UI utilizando técnicas que permiten cambiar de tamaño de forma fácil(as described in the Best Practices, below).

Nota: Las caracteristicas que definen el tamaño y la densidad generalizadas de dispositivo son independientes unos de otros. Por ejmplo, una pantalla WVGA high-density screen es considerada una pantalla de tamaño normal porque su tamaño físico es el mismo que el  T-Mobile G1 (El primer dispositivo Android y configuración de pantalla base). De otra parte una WVGA medium-density screen se considera una pantalla de tamaño large. Aunque ofrece la misma resolución (el mismo número de pixeles), la WVGA medium-density screen tiene una densidad lower, significando que cada pixel es fisicamente más grande y , asi , la pantalla completa es larger comparada con  la pantalla normal.

Independencia de Densidad

Tu aplicación consigue “independencia de densidad” cuando conserva el tamaño físico (desde el punto de vista del usuario) de los elementos del interfaz del usuario cuando es mostrada en pantallas con distintas densidades.

Mantener la independencia de densidad es importante porque , sin ella, un elemento del UI (tal como un boton) aparece físicamente más grande en una pantalla con baja densidad y más pequeña en pantallas de densidades altas. Tales cambios de tamaño relacionados con la densidad puede hacer que tu layout se vea mal o en que sea tu aplicación poco usable. Las siguientes imagenes muestran las diferencias entre una aplicación cuando no proporciona independencia de densidad y cuando sí lo hace.

Figura 2. Ejemplo de aplicación sin soporte para distintas densidades.

Figure 3. Ejemplo de aplicación con un buen soporte de distintas densidades.

El sistema Android te ayuda a que tu app consiga independencia de densidad en dos maneras:

  • El sistema escala las unidades dp de forma apropiada para la actual densidad de pantalla
  • El sistema escala recursos drawable para el tamaño apropiado, basandose en la densidad actual de pantalla, si es necesario.

En la figura 2, el text view y el bitmap (recurso drawable) tienen dimensiones especificadas en pixeles (unidades px), de forma que las formas son físicamente más grandes en pantallas con densidades bajas y más pequeñas en pantallas con densidades altas. Esto  es porque , aunque los tamaños de las pantallas son las mismas, la densidad alta tiene más pixeles por pulgada (o dicho de otro modo el mismo número de pixeles caben en un área más pequeña).En la figura 3,  las dimensiones del layout son especificadas en unidades dp. Debido a que la configuración base de los pixeles independientes de densidad es para una pantalla de densidad media (medium), el dispositivo que tenga una pantalla de densidad medium aparece el mismo que en la figura 2. Y en las pantallas de baja y de alta densidad, sin embargo, el sistema escala el valor de pixeles independiente de la densidad arriba o abajo, respectivamente , para ajustarse a la pantalla apropiada.

En la mayoria de los casos, puedes asegurar independencia de densidad en tu app simplemente especificando todas las dimensiones de layout con unidades dp o con “wrap_content”, según sea el caso.El sistema entonces escala los bitmap drawables para mostrarlos en el tamaño apropiado, basandose en el factor de escalado apropiado para la densidad actual de la pantalla.

Sin embargo, el escalado de los bitmap puede resultar en bitmaps borrosos o pixelados. Para eliminar estos accidentes, lo mejor es proporcionar recursos bitmap alternativos para distintas densidades. Por ejemplo, debes proporcionar bitmaps de alta resolución para pantallas de densidades altas y el sistema utilizará éstas en vez de cambiar el tamaño del bitmap diseñado para pantallas de densidad media.

En la siguiente sección describimos más sobre cómo proporcionar recursos alternativos para distintas configuraciones de pantalla.

Cómo soportar multiples pantallas

La fundación del soporte de Android para múltiples pantallas tiene como objetivo que el renderizado del layout de la aplicación y de los bitmaps sea apropiado para la configuración de pantalla que toque. El sistema se encarga de la mayoria del trabajo escalando los layouts al tamaño/densidad de la pantalla y escalando los bitmaps a la densidad de la pantalla que se tiene. Pero para que que tu app sea optima en las distintas configuraciones de pantalla además debemos tener en cuenta:

  • Declarar explicitamente en el manifest qué tamaños de pantalla soporta nuestra app.By declaring which screen sizes your application supports, you can ensure that only devices with the screens you support can download your application. Declaring support for different screen sizes can also affect how the system draws your application on larger screens—specifically, whether your application runs in screen compatibility mode.To declare the screen sizes your application supports, you should include the <supports-screens> element in your manifest file.
  • Proporcionar distintos layouts para distintos tamaños de pantallas.By default, Android resizes your application layout to fit the current device screen. In most cases, this works fine. In other cases, your UI might not look as good and might need adjustments for different screen sizes. For example, on a larger screen, you might want to adjust the position and size of some elements to take advantage of the additional screen space, or on a smaller screen, you might need to adjust sizes so that everything can fit on the screen.The configuration qualifiers you can use to provide size-specific resources are smallnormallarge, and xlarge. For example, layouts for an extra large screen should go inlayout-xlarge/.Beginning with Android 3.2 (API level 13), the above size groups are deprecated and you should instead use the sw<N>dp configuration qualifier to define the smallest available width required by your layout resources. For example, if your multi-pane tablet layout requires at least 600dp of screen width, you should place it in layout-sw600dp/. Using the new techniques for declaring layout resources is discussed further in the section about Declaring Tablet Layouts for Android 3.2.
  • Proporcionar bitmaps a distintos tamaños para distintas densidades de pantalla.By default, Android scales your bitmap drawables (.png.jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate physical size on each device. For example, if your application provides bitmap drawables only for the baseline, medium screen density (mdpi), then the system scales them up when on a high-density screen, and scales them down when on a low-density screen. This scaling can cause artifacts in the bitmaps. To ensure your bitmaps look their best, you should include alternative versions at different resolutions for different screen densities.The configuration qualifiers you can use for density-specific resources are ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high). For example, bitmaps for high-density screens should go in drawable-hdpi/.

The size and density configuration qualifiers correspond to the generalized sizes and densities described in Range of screens supported, above.

Note: If you’re not familiar with configuration qualifiers and how the system uses them to apply alternative resources, read Providing Alternative Resources for more information.

At runtime, the system ensures the best possible display on the current screen with the following procedure for any given resource:

  1. The system uses the appropriate alternative resourceBased on the size and density of the current screen, the system uses any size- and density-specific resource provided in your application. For example, if the device has a high-density screen and the application requests a drawable resource, the system looks for a drawable resource directory that best matches the device configuration. Depending on the other alternative resources available, a resource directory with the hdpi qualifier (such as drawable-hdpi/) might be the best match, so the system uses the drawable resource from this directory.
  2. If no matching resource is available, the system uses the default resource and scales it up or down as needed to match the current screen size and densityThe “default” resources are those that are not tagged with a configuration qualifier. For example, the resources in drawable/ are the default drawable resources. The system assumes that default resources are designed for the baseline screen size and density, which is a normal screen size and a medium density. As such, the system scales default density resources up for high-density screens and down for low-density screens, as appropriate.However, when the system is looking for a density-specific resource and does not find it in the density-specific directory, it won’t always use the default resources. The system may instead use one of the other density-specific resources in order to provide better results when scaling. For example, when looking for a low-density resource and it is not available, the system prefers to scale-down the high-density version of the resource, because the system can easily scale a high-density resource down to low-density by a factor of 0.5, with fewer artifacts, compared to scaling a medium-density resource by a factor of 0.75.

For more information about how Android selects alternative resources by matching configuration qualifiers to the device configuration, read How Android Finds the Best-matching Resource.

Utilizar cualificadores de configuración

Android supports several configuration qualifiers that allow you to control how the system selects your alternative resources based on the characteristics of the current device screen. A configuration qualifier is a string that you can append to a resource directory in your Android project and specifies the configuration for which the resources inside are designed.

To use a configuration qualifier:

  1. Create a new directory in your project’s res/ directory and name it using the format: <resources_name>-<qualifier>
    • <resources_name> is the standard resource name (such as drawable or layout).
    • <qualifier> is a configuration qualifier from table 1, below, specifying the screen configuration for which these resources are to be used (such as hdpi or xlarge).

    You can use more than one <qualifier> at a time—simply separate each qualifier with a dash.

  2. Save the appropriate configuration-specific resources in this new directory. The resource files must be named exactly the same as the default resource files.

For example, xlarge is a configuration qualifier for extra large screens. When you append this string to a resource directory name (such as layout-xlarge), it indicates to the system that these resources are to be used on devices that have an extra large screen.

Table 1. Configuration qualifiers that allow you to provide special resources for different screen configurations.

Screen characteristic Qualifier Description
Size small Resources for small size screens.
normal Resources for normal size screens. (This is the baseline size.)
large Resources for large size screens.
xlarge Resources for extra large size screens.
Density ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
nodpi Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen’s density.
tvdpi Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a “primary” density group. It is mostly intended for televisions and most apps shouldn’t need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate. If you find it necessary to provide tvdpi resources, you should size them at a factor of 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi.
Orientation land Resources for screens in the landscape orientation (wide aspect ratio).
port Resources for screens in the portrait orientation (tall aspect ratio).
Aspect ratio long Resources for screens that have a significantly taller or wider aspect ratio (when in portrait or landscape orientation, respectively) than the baseline screen configuration.
notlong Resources for use screens that have an aspect ratio that is similar to the baseline screen configuration.

Note: If you’re developing your application for Android 3.2 and higher, see the section about Declaring Tablet Layouts for Android 3.2 for information about new configuration qualifiers that you should use when declaring layout resources for specific screen sizes (instead of using the size qualifiers in table 1).

For more information about how these qualifiers roughly correspond to real screen sizes and densities, see Range of Screens Supported, earlier in this document.

For example, the following is a list of resource directories in an application that provides different layout designs for different screen sizes and different bitmap drawables for medium, high, and extra high density screens.

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size
res/layout-large/my_layout.xml       // layout for large screen size
res/layout-xlarge/my_layout.xml      // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

res/drawable-mdpi/my_icon.png        // bitmap for medium density
res/drawable-hdpi/my_icon.png        // bitmap for high density
res/drawable-xhdpi/my_icon.png       // bitmap for extra high density

For more information about how to use alternative resources and a complete list of configuration qualifiers (not just for screen configurations), see Providing Alternative Resources.

Be aware that, when the Android system picks which resources to use at runtime, it uses certain logic to determing the “best matching” resources. That is, the qualifiers you use don’t have to exactly match the current screen configuration in all cases in order for the system to use them. Specifically, when selecting resources based on the size qualifiers, the system will use resources designed for a screen smaller than the current screen if there are no resources that better match (for example, a large-size screen will use normal-size screen resources if necessary). However, if the only available resources are larger than the current screen, the system will not use them and your application will crash if no other resources match the device configuration (for example, if all layout resources are tagged with the xlarge qualifier, but the device is a normal-size screen). For more information about how the system selects resources, read How Android Finds the Best-matching Resource.

Tip: If you have some drawable resources that the system should never scale (perhaps because you perform some adjustments to the image yourself at runtime), you should place them in a directory with the nodpi configuration qualifier. Resources with this qualifier are considered density-agnostic and the system will not scale them.

Diseñando layouts y recursos drawables alternativos

Los tipos de recursos alternativos que debes crear depende de las necesidades de tu app. Generalmente, debes utilizar los cualificadores del tamaño y orientación para proporcionar layouts y bitmaps alternativos.

Las siguientes secciones recumen como querrias utilizar los cualificadores de tamaño y densidad para proporcionar layouts y bitmaps alternativos.

Layouts alternativos

Generalmente, tú sabrás si necesitas layouts alternativos para distintos tamaños de pantalla una vez que pruebas tu app en diferentes configuraciones de pantalla. Por ejemplo:

  • Cuando probamos en un pantalla small, puedes descubrir que tu layout no cabe en la pantalla. Por ejemplo, una fila de botones puede no caber a la anchura de la pantalla en una pequela. En este caso debes proporcionar un layout alternativo para pequeñas pantallas que se ajuste al tamaño y posición de los botones.
  • Cuando se prueba en una pantalla extra large , puedes ver que no se hace un eficiente uso del gran espacio que tienes en pantalla. En este caso hacemos un layout alternativo para extra large screens that provides a redesigned UI that is optimized for bigger screens such as tablets.Although your application should work fine without an alternative layout on big screens, it’s quite important to users that your application looks as though it’s designed specifically for their devices. If the UI is obviously stretched, users are more likely to be unsatisfied with the application experience.
  • Y, cuando se prueba en el cambio de orientación landscape-portrait. te puede pasar que los elementos del interfaz colocados al fondo de la pantalla en la orientación portrait deberian estar a la derecha en modo landscape.

Para resumir , cuando haces el layout debes asegurarte que:

  • Cabe en pantallas pequeñas
  • Está optimizado para pantallas grandes que aprovechan bien el espacio adicional.
  • Está optimizado para las orientaciones landscape y portrait.

Si tu interfaz utiliza bitmaps que necesitan ajustarse al tamaño de la vista incluso después de que el sistema escala el layout (como por ejemplo una imagen de fondo en un boton), entonces debes utilizar lo que se llaman Nine-Patch bitmap files. Los ficheros de este tipo son básicamente PNGs en los cuales especificamos un region de dos dimensiones que es estrechable. Asi cuando el sistema escala la vista donde esta este tipo de bitmaps, el sistema estrechará el Nine-Patch bitmap, pero solo en la región especificada.Por tanto , no necesitas proporcionar distintos drawables para distintos tamaños de pantalla, porque el Nine-Patch bitmap se puede ajustar a cualquier tamaño. De bes , sin embargo, proporcionar distintas versiones de Nine-Patch bitmaps en el caso de diferentes densidades.

Recursos Drawables alternativos

Figure 4. Tamaños relativos de los bitmaps drawables en las densidades generalizadas

Casi todas las aplicaciones deben tener recursos bitmap alternativos para distintas densidades de pantalla, porque casi todas las apps tienen un launcher icon y ese icono debe verse bien en todas las densidades.

Nota:Solo necesita proporcionar recursos gráficos especificos para ficheros bitmap (.png.jpg, or .gif) y ficheros Nine-Path (.9.png).Si utilizas ficheros XML para definir formas , colores u otros recursos drawables, basta con una copia en drawable/.

Para crear recursos drawable alternativos para distintas densidades, debes seguir  el 3:4:6:8 scaling ratio que hay entre las cuatro densidades generalizadas. Por ejemplo, si tienes un bitmap de 48×48 pixeles en pantallas de densidad medium (el tamaño del launcher icon), todos los diferentes tamaños deben ser:

  • 36×36 para low-density
  • 48×48 para medium-density
  • 72×72 para high-density
  • 96×96 para extra high-density

Para más información sobre el diseño de iconos, ver las Icon Design Guidelines, que incluye información de tamaño para varios bitmap dibujables, tales como ic0nos launcher, iconos de menu, iconos de barra de estado, tab icons y más

Declaring Tablet Layouts for Android 3.2

-TODO-

Mejores prácticas

El objetivo de soportar múltiples tipos de pantallas es crear una aplicación que pueda funcionar bien y tener buen aspecto en todas las configuraciones de pantalla generalizadas soportadas por Android. Las secciones prévias de este documento proporcionan información sobre como Android adapta tu app a las configuraciones de pantalla y como personalizar el aspecto de tu app en distintas configuraciones de pantalla. Esta sección proporciona trucos adicionales y técnicas que te ayudan a asegurar que tu app escala bien para los distintos tipos de pantalla.

Aqui vemos una rápida lista sobre como asegurar que tu app muestra las pantallas bien en distintos tipos de pantallas:

  1. Utiliza wrap_contentfill_parent, o unidades dp cuando vayas a especificar dimensiones en un fichero XML.
  2. No utilices valores “a capon” en valores de pixeles en el código de tu app
  3. No utilices AbsoluteLayout (esta deprecado)
  4. Proporciona recursos drawable alternativos para distintas densidades de pantalla

En las siguientes secciones proporcionaremos más detalles.

1.Utilizar wrap_content, fill_parent, o las unidades dp para los dimensiones de los layout

Cuando definimos los valores de android:layout_width y de android:layout_height en las Views definidas en los layout XML, utilizar  "wrap_content""fill_parent" o las unidades dp units te garantiza que la vista adquirirá un tamaño apropiado según la configuración de pantalla que le toque.

Por ejemplo, una view con  layout_width="100dp" mide 100 pixeles en una pantalla de densidad media y el sistema escala a 150 pixeles en pantallas de densidad alta, de forma que la view ocupa aproximadamente el mismo espacio físico en la pantalla.

Similarmente, debes preferir las unidades sp (scale-independent pixel) para definir los tamaños de los textos. El factor de escala sp depende de la configuración del usuario y el sistema escala el tamaño de la misma forma que lo hace con los dp.

2. No utilices valores de pixeles a capón en el código de tu app

Por razones de rendimiento y para mantener el código más simple, el sistema Android utiliza pixeles como la unidad estandar para expresar dimensiones y valores de coordenadas. Esto significa que las dimensiones de una view están siempre expresadas en el código utilizando píxeles, aunque siempre basados en la densidad de pantalla actual. Por ejemplo si myView.getWidth() retorna 10, el view es de 10 pixeles de ancho en la pantalla actual, pero en un dispositivo con una densidad de pantalla más alta, el valor retornado podría ser de 15. Si utilizas valores de píxeles en el código de tu app para trabajar con bitmaps que no están pre-escalados para la densidad de pantalla actual, puede que necesites escalar los valores de pixeles que usas en tu código para que se corresponda con un bitmap no  escalado.

Si tu app manipula bitmaps o trata con valores de pixeles en tiempo de ejecución, ver la sección Additional Density Considerations.

3. No utilices AbsoluteLayout

A diferencia de otros patrones de layout,  AbsoluteLayout te obliga a utilizar posiciones fijas para colocar los elementos de la view, lo cual puede fácilmente dirigir a interfaces de usuario que no funcionar en pantallas diferentes. Es por ello que este sistema de layout fue deprecado en  Android 1.5 (API Level 3).

Debes en su vez utilizar  RelativeLayout, que utiliza posicionamiento relativo para colocar los elementos de la view. Por ejemplo,  puedes especificar que un widget de botón debe aparecer a la derecha de un elemento de texto.

4. Utiliza recursos personalizados por tamaño-densidad

Aunque el sistema escala tu layout y recursos drawable basandose en la configuración actual de pantalla, tu puedes querar hacer ajustes del UI en distintos tamaños de pantallas y proporcionar bitmap drawables optimizados para diversas densidades.

If you need to control exactly how your application will look on various screen configurations, adjust your layouts and bitmap drawables in configuration-specific resource directories. For example, consider an icon that you want to display on medium and high density screens. Simply create your icon at two different sizes (for instance 100×100 for medium density and 150×150 for high density) and put the two variations in the appropriate directories, using the proper qualifiers:

res/drawable-mdpi/icon.png   //for medium-density screens
res/drawable-hdpi/icon.png   //for high-density screens

Note: If a density qualifier is not defined in a directory name, the system assumes that the resources in that directory are designed for the baseline medium density and will scale for other densities as appropriate.

For more information about valid configuration qualifiers, see Using configuration qualifiers, earlier in this document.

Additional Density Considerations

This section describes more about how Android performs scaling for bitmap drawables on different screen densities and how you can further control how bitmaps are drawn on different densities. The information in this section shouldn’t be important to most applications, unless you have encountered problems in your application when running on different screen densities or your application manipulates graphics.

To better understand how you can support multiple densities when manipulating graphics at runtime, you should understand that the system helps ensure the proper scale for bitmaps in the following ways:

  1. Pre-scaling of resources (such as bitmap drawables) Based on the density of the current screen, the system uses any size- or density-specific resources from your application and displays them without scaling. If resources are not available in the correct density, the system loads the default resources and scales them up or down as needed to match the current screen’s density. The system assumes that default resources (those from a directory without configuration qualifiers) are designed for the baseline screen density (mdpi), unless they are loaded from a density-specific resource directory. Pre-scaling is, thus, what the system does when resizing a bitmap to the appropriate size for the current screen density.If you request the dimensions of a pre-scaled resource, the system returns values representing the dimensions after scaling. For example, a bitmap designed at 50×50 pixels for an mdpi screen is scaled to 75×75 pixels on an hdpi screen (if there is no alternative resource for hdpi) and the system reports the size as such.There are some situations in which you might not want Android to pre-scale a resource. The easiest way to avoid pre-scaling is to put the resource in a resource directory with thenodpi configuration qualifier. For example:
    res/drawable-nodpi/icon.png

    When the system uses the icon.png bitmap from this folder, it does not scale it based on the current device density.

  2. Auto-scaling of pixel dimensions and coordinates An application can disable pre-scaling by setting android:anyDensity to "false" in the manifest or programmatically for a Bitmap by setting inScaled to "false". In this case, the system auto-scales any absolute pixel coordinates and pixel dimension values at draw time. It does this to ensure that pixel-defined screen elements are still displayed at approximately the same physical size as they would be at the baseline screen density (mdpi). The system handles this scaling transparently to the application and reports the scaled pixel dimensions to the application, rather than physical pixel dimensions.For instance, suppose a device has a WVGA high-density screen, which is 480×800 and about the same size as a traditional HVGA screen, but it’s running an application that has disabled pre-scaling. In this case, the system will “lie” to the application when it queries for screen dimensions, and report 320×533 (the approximate mdpi translation for the screen density). Then, when the application does drawing operations, such as invalidating the rectangle from (10,10) to (100, 100), the system transforms the coordinates by scaling them the appropriate amount, and actually invalidate the region (15,15) to (150, 150). This discrepancy may cause unexpected behavior if your application directly manipulates the scaled bitmap, but this is considered a reasonable trade-off to keep the performance of applications as good as possible. If you encounter this situation, read the following section aboutConverting dp units to pixel units.Usually, you should not disable pre-scaling. The best way to support multiple screens is to follow the basic techniques described above in How to Support Multiple Screens.

If your application manipulates bitmaps or directly interacts with pixels on the screen in some other way, you might need to take additional steps to support different screen densities. For example, if you respond to touch gestures by counting the number of pixels that a finger crosses, you need to use the appropriate density-independent pixel values, instead of actual pixels.

Scaling Bitmap objects created at runtime

Figure 5. Comparison of pre-scaled and auto-scaled bitmaps, from ApiDemos.

If your application creates an in-memory bitmap (a Bitmap object), the system assumes that the bitmap is designed for the baseline medium-density screen, by default, and auto-scales the bitmap at draw time. The system applies “auto-scaling” to aBitmap when the bitmap has unspecified density properties. If you don’t properly account for the current device’s screen density and specify the bitmap’s density properties, the auto-scaling can result in scaling artifacts the same as when you don’t provide alternative resources.

To control whether a Bitmap created at runtime is scaled or not, you can specify the density of the bitmap withsetDensity(), passing a density constant from DisplayMetrics, such as DENSITY_HIGH or DENSITY_LOW.

If you’re creating a Bitmap using BitmapFactory, such as from a file or a stream, you can useBitmapFactory.Options to define properties of the bitmap as it already exists, which determine if or how the system will scale it. For example, you can use the inDensity field to define the density for which the bitmap is designed and theinScaled field to specify whether the bitmap should scale to match the current device’s screen density.

If you set the inScaled field to false, then you disable any pre-scaling that the system may apply to the bitmap and the system will then auto-scale it at draw time. Using auto-scaling instead of pre-scaling can be more CPU expensive, but uses less memory.

Figure 5 demonstrates the results of the pre-scale and auto-scale mechanisms when loading low (120), medium (160) and high (240) density bitmaps on a high-density screen. The differences are subtle, because all of the bitmaps are being scaled to match the current screen density, however the scaled bitmaps have slightly different appearances depending on whether they are pre-scaled or auto-scaled at draw time. You can find the source code for this sample application, which demonstrates using pre-scaled and auto-scaled bitmaps, in ApiDemos.

Note: In Android 3.0 and above, there should be no perceivable difference between pre-scaled and auto-scaled bitmaps, due to improvements in the graphics framework.

Converting dp units to pixel units

In some cases, you will need to express dimensions in dp and then convert them to pixels. Imagine an application in which a scroll or fling gesture is recognized after the user’s finger has moved by at least 16 pixels. On a baseline screen, a user’s must move by 16 pixels / 160 dpi, which equals 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a device with a high density display (240dpi), the user’s must move by 16 pixels / 240 dpi, which equals 1/15th of an inch (or 1.7 mm). The distance is much shorter and the application thus appears more sensitive to the user.

To fix this issue, the gesture threshold must be expressed in code in dp and then converted to actual pixels. For example:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

The DisplayMetrics.density field specifies the scale factor you must use to convert dp units to pixels, according to the current screen density. On a medium-density screen,DisplayMetrics.density equals 1.0; on a high-density screen it equals 1.5; on an extra high-density screen, it equals 2.0; and on a low-density screen, it equals 0.75. This figure is the factor by which you should multiply the dp units on order to get the actual pixel count for the current screen. (Then add 0.5f to round the figure up to the nearest whole number, when converting to an integer.) For more information, refer to the DisplayMetrics class.

However, instead of defining an arbitrary threshold for this kind of event, you should use pre-scaled configuration values that are available from ViewConfiguration.

Using pre-scaled configuration values

You can use the ViewConfiguration class to access common distances, speeds, and times used by the Android system. For instance, the distance in pixels used by the framework as the scroll threshold can be obtained with getScaledTouchSlop():

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

Methods in ViewConfiguration starting with the getScaled prefix are guaranteed to return a value in pixels that will display properly regardless of the current screen density.

Cómo probar tu aplicación en pantallas diferentes

Figure 6. Varias tipos de dispositivos A set of AVDs for testing screens support.

Antes de publicar tu app, debes probarla en todas las densidades y tamaños de pantallas soportados. El Android SDK incluye varios skins de emuladores que puedes usar, que replican los tamaños y densidades de las configuraciones de pantalla comunes en las cuales tu app va a ejecutarse. Puedes modificar el tamño por defecto, densidad, y la resolución de las skins de los emuladores para replicar las caracteristicas de cualquier pantalla especifica.

To set up an environment for testing your application’s screen support, you should create a series of AVDs (Android Virtual Devices), using emulator skins and screen configurations that emulate the screen sizes and densities you want your application to support. To do so, you can use the AVD Manager to create the AVDs and launch them with a graphical interface.

To launch the Android SDK Manager, execute the SDK Manager.exe from your Android SDK directory (on Windows only) or execute android from the <sdk>/tools/ directory (on all platforms). Figure 6 shows the AVD Manager with a selection of AVDs, for testing various screen configurations.

Table 3 shows the various emulator skins that are available in the Android SDK, which you can use to emulate some of the most common screen configurations.

For more information about creating and using AVDs to test your application, see Managing AVDs with AVD Manager.

Table 3. Various screen configurations available from emulator skins in the Android SDK (indicated in bold) and other representative resolutions.

Low density (120), ldpi Medium density (160), mdpi High density (240), hdpi Extra high density (320), xhdpi
Small screen QVGA (240×320) 480×640
Normal screen WQVGA400 (240×400)
WQVGA432 (240×432)
HVGA (320×480) WVGA800 (480×800)
WVGA854 (480×854)
600×1024
640×960
Large screen WVGA800** (480×800)
WVGA854** (480×854)
WVGA800* (480×800)
WVGA854* (480×854)
600×1024
Extra Large screen 1024×600 WXGA (1280×800)
1024×768
1280×768
1536×1152
1920×1152
1920×1200
2048×1536
2560×1536
2560×1600
* To emulate this configuration, specify a custom density of 160 when creating an AVD that uses a WVGA800 or WVGA854 skin.
** To emulate this configuration, specify a custom density of 120 when creating an AVD that uses a WVGA800 or WVGA854 skin.
† This skin is available with the Android 3.0 platform

To see the relative numbers of active devices that support any given screen configuration, see the Screen Sizes and Densities dashboard.

Figure 7. Size and density options you can set, when starting an AVD from the AVD Manager.

We also recommend that you test your application in an emulator that is set up to run at a physical size that closely matches an actual device. This makes it a lot easier to compare the results at various sizes and densities. To do so you need to know the approximate density, in dpi, of your computer monitor (for instance, a 30″ Dell monitor has a density of about 96 dpi). When you launch an AVD from the AVD Manager, you can specify the screen size for the emulator and your monitor dpi in the Launch Options, as shown in figure 7.

If you would like to test your application on a screen that uses a resolution or density not supported by the built-in skins, you can create an AVD that uses a custom resolution or density. When creating the AVD from the AVD Manager, specify the Resolution, instead of selecting a Built-in Skin.

If you are launching your AVD from the command line, you can specify the scale for the emulator with the -scale option. For example:

emulator -avd <avd_name> -scale 96dpi

To refine the size of the emulator, you can instead pass the -scale option a number between 0.1 and 3 that represents the desired scaling factor.

For more information about creating AVDs from the command line, see Managing AVDs from the Command Line