Tip Android #33: Dimensiones relativas

18/05/2014
android tip

Debido a la amplísima diversidad de dispositivos móviles que ejecutan Android es imprescindible diseñar interfaces adaptadas a las resoluciones/densidades de pantalla más comunes y en numerosas ocasiones resulta necesario tener layouts distintos con el objetivo de que nuestra app utilice de forma óptima e inteligente toda la pantalla diponible ya se trate, por ejemplo,de una tablet de 7 pulgadas en posición horizontal (landscape) o de un móvil de 4″ en vertical.

Independientemente de las soluciones elegidas, es imprescindible al hacer un buen diseño utilizar siempre unidades relativas que puedan reescarlarse fácilmente de forma automática a cualquier tamaño de pantalla. En Android tenemos los siguientes tipos de unidades de medida para el diseño de interfaces:

  • Fijas

    • px:Representa un píxel.
    • in : pulgada (25,4 mm) según el tamaño físico de la pantalla.
    • mm: milímetro.
    • pt: punto, la 1/72 parte de una pulgada.
  • Relativas
    • dp: Píxel independiente de la densidad. Permite definir un tamaño relativo a la densidad de píxeles en pantalla siendo 1 dp un píxel en una pantalla de densidad 160dpi. Para calcular su tamaño, tenemos que px = dp * (dpi / 160) y que el tamaño físico de la pantalla es irrelevante.
    • sp: píxel independiente de la escala. Es equivalente a dp pero teniendo en cuenta la “escala” que el usaurio ha definido para el tamaño de las fuentes

Utilizaremos siempre que sea posible unidades dp (y sp para el tamaño de fuentes) para asegurar que los elementos de nuestros layout tengan el mismo tamaño físico (de forma no exacta pero muy aproximada) en cualquier pantalla. Con respecto a esto último, también tenemos que tener en cuenta que los dispositvos Android se clasifican según la densidad de su pantalla en las siguientes categorías que pueden usarse como cuantificadores para redefinir layout o cualquier otro fichero de recursos para una densidad especificada.

dpi tipo ejemplos
120 ldpi Galaxy mini, HTC Wildfire
160 mdpi Galaxy ACE, HTC Wildfire S
213 tvdpi Nexus 7 2012
240 hdpi HTC Desire, LG G2, Galaxy S2, Galaxy ACE 2
320 xhdpi Nexus 7 2013, Galaxy Nexus,Nexus 4, Galaxy S3, Moto G
480 xxhdpi Nexus 5, Galaxy S4, Galaxy S5, HTC One, Xperia Z
640 xxxhdpi

Este valor se puede obtener programáticamente de forma sencilla:

DisplayMetrics metrics = getResources().getDisplayMetrics();

Es una buena práctica definir constantes para los tamaños que usemos puesto que lo habitual es que estos se repitan. Estas declaraciones se realizarán en un fichero de recursos normalmente denominado /res/values/dimens.xml.

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="small_button">32dp</dimen>
   <dimen name="normal_button">48dp</dimen>
   <dimen name="large_button">64dp</dimen>
   <dimen name="small_text">12sp</dimen>
   <dimen name="normal_text">14sp</dimen>
   <dimen name="large_text">16sp</dimen>
</resources>

Estas constantes se usarían de la siguiente forma

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" 
        android:textSize="@dimen/small_text"/>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" 
        android:textSize="@dimen/normal_text"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" 
        android:textSize="@dimen/large_text"/>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 
        android:textSize="@dimen/small_button"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 
        android:textSize="@dimen/normal_button"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 
        android:textSize="@dimen/large_button"/>

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" 
        android:layout_gravity="center_horizontal"/>

</LinearLayout>

La siguiente imagen muestra el layout en un Samsung Galaxy Nexus (4,65″, 315dpi) y en un Galaxy ACE (3.5″, 164 dpi )

android relative dimensions

Podemos hilar más fino todavía y establecer el tamaño de las dimensiones relativas de forma específica para cierta densidad/posición de pantalla. Para ello creamos los directorios /res/values-[densidad-resolucion]-[formato] que sean necesarios y ubicamos en los mismos la versión de dimens.xml correspondiente, por ejemplo /res/values-mdpi/dimens.xml, /res/values-sw600dp-land/dimens.xml…Es decir, procedemos de forma similar que cuando queremos especificar layouts o drawables en función de la pantalla del dispositivo.

El proyecto completo para Eclipse ADT se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.

<< TIPS ANDROID

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: