Curso de Introducción a Android - Sesión 6: App Resources y App Manifest

 
SEGUIR LEYENDO
Curso de Introducción a Android - Sesión 6: App Resources y App Manifest
Curso de Introducción a Android

Sesión 6: App Resources y App Manifest

Introducción

Como se ha visto en anteriores sesiones, Android hace por regla general un uso intensivo de los
llamados recursos o resources, archivos importantes para el funcionamiento de la app que no están
conformados por código Java.

En esta sesión se estudiará en profundidad la gestión de los resources y cómo cambiar de unos a
otros según la configuración del dispositivo (tamaño y orientación de pantalla, idioma, versión de la
API...).

Recursos y su organización

Todos los recursos de la app se encuentran en la carpeta res. Esta carpeta está en
 app/src/main/res en Android Studio y a su vez cuenta con subcarpetas para organizar los
recursos:

     animator: animaciones de propiedades (Android 3.0+) en XML.
     anim: animaciones y animaciones de propiedades declaradas en XML.
     color: listas de colores en XML aplicables a Views según su estado (pulsado, activada,
     desactivada, etc.).
     drawable: imágenes y drawables declarados en XML:
            Archivos .png, .jpg, .9.png y .gif.
            State-lists: archivos XML que asignan un drawable a cada estado de un View (activo,
            pulsado, etc.).
            Shapes: archivos XML que crean drawables a partir de formas (rectángulo, óvalo, línea,
            etc.).
            Animation Drawables: archivos XML que definen una animación creada a partir de una serie
            de imágenes.
     layout: layouts con las configuraciones de la interfaz en XML.
     menu: menús declarados en XML.
     raw: aquí van los archivos que se van a usar como recursos pero no cuadran en ninguna otra
     carpeta, como sonidos, vídeos, etc.
     values: valores simples como strings, colores, dimensiones o enteros. Por regla general se
     tienen los siguientes archivos:
             arrays.xml : almacena arrays de datos (string, ints, referencias a otros recursos).
             colors.xml : almacena colores asignándoles un nombre.
             dimens.xml : almacena dimensiones, tamaños de Views, márgenes, paddings, etc.
Curso de Introducción a Android - Sesión 6: App Resources y App Manifest
strings.xml : almacena cadenas de texto.
           styles.xml : almacena estilos y temas aplicables a Views o a Activities.
    xml: almacena archivos XML en general (por ejemplo, Preferences).

Aparte de estos nombres de carpeta, Android permite añadir sufijos para que los recursos que maneje
la aplicación concuerden con la configuración del dispositivo.

Aunque se van a dar ejemplos concretos, estos sufijos pueden añadirse a cualquier carpeta, depende
del desarrollador saber si tiene sentido o no hacerlo así. Además, estos sufijos pueden combinarse,
pudiendo tener por ejemplo values-es y values-es-land .

Otro punto importante es que estos valores sólo sobreescriben otros valores de la carpeta por defecto.
Es decir, si tenemos un values/strings.xml con
 PC y sabemos que PC es igual en español, no
necesitaremos un values-es/string.xml con el mismo valor (aunque Android por seguridad
nos pedirá que lo pongamos).

Aparte, podemos distinguir entre los recursos del propio proyecto y los de Android mediante
 @android:xxxxx/ y @xxxxxx/ . En @color/ tendríamos los colores que hayamos definido
en el proyecto y en @android:color/ los colores que el SDK de Android usa internamente.

Algunos ejemplos de modificadores son:

Densidad de píxeles

Aunque Android por defecto hace escala de los drawables, puede ser interesante especificar
drawables distintos si por ejemplo al tener muy poca densidad de píxeles se pierden detalles. Los
distintos valores se miden a partir del valor de mdpi y se multiplican por un factor para saber el
tamaño que debería tener.

    ldpi: 0.75 (en desuso)
    mdpi: 1.0
    hdpi: 1.5
    xhdpi: 2.0
    xxhdpi: 3.0
    xxxhdpi: 4.0

Para Android TV tenemos también tvdpi con un factor de escala de 1.33.

Esto quiere decir que si tenemos una imagen que en mdpi son 40x40px, en ldpi debería ser de
30x30px y en xhdpi 80x80px.
Curso de Introducción a Android - Sesión 6: App Resources y App Manifest
Los nombres de las carpetas serían drawable-xxxx : drawable-ldpi, drawable-hdpi, etc.

Si quisiéramos meter imágenes que no se reescalen nunca usaríamos drawable-nodpi .

Tamaño de pantalla

Hay varias formas de tratar las configuraciones.

Tamaño general:

Se miden por su tamaño máximo en dp. Las siguientes medidas significan "hasta ese valor sin
incluírlo", es decir, si se alcanza estaríamos en la siguiente configuración.

     small: hasta 320x470dp (QVGA).
     normal: hasta 480x640dp (HVGA y WVGA).
     large: hasta 720x960dp (VGA y WVGA).
     xlarge: todas las que sean más grandes.
De esta forma tendríamos por ejemplo layout-large , layout-small , etc.

Tamaño mínimo:

Para esto tenemos el modificador sw___dp , que nos permite especificar unos dp mínimos de
ancho para el dispositivo. Tenemos por ejemplo que sw600dp suele ser para tablets de 7" y
 sw720dp para tablets de 10".

Este "ancho" se mantiene entre cambios de orientación horizontal y vertical, es decir, aunque se gire,
se toma como ancho "el valor más grande de ancho y alto".

Por el contrario, con los modificadores w___dp y h___dp aunque sirven para lo mismo, este
valor no se mantiene. Es decir, si tenemos un tablet de 600x360dp en vertical cogería los recursos
que hubiese en layout_w600dp , pero si lo giramos pasaría a ser de 360x600dp y ya no entraría,
aunque sí lo haría a una carpeta layout_h600dp .

Orientación

Podemos cambiar el valor de los distintos recursos según la orientación de pantalla con los
modificadores port (vertical) y land (horizontal), aunque se suele usar sólo este último, ya que
sin modificador se interpreta como port igualmente.
Así, podríamos tener distintos layouts para vertical y horizontal con layout y layout-land o
incluso si sabemos que en hoizontal un texto puede contener más información, podríamos tener
distintos strings.xml en values y values-land .

Tipo de dispositivo:

Aquí podemos configurar recursos para los distintos tipos de dispositivos:

    car: para coche, en un dock.
    desk: en un dock de escritorio.
    television: el dispositivo está conectado a una TV (Android TV, ChromeCast, Stick USB con
    Android)...
    appliance: el dispositivo no tiene pantalla.
    watch: el dispositivo es un reloj (Android Wear).

Idioma

Podemos configurar los recursos para cada idioma, con los formatos idioma_REGION o
simplemente idioma . Por ejemplo, para inglés tendríamos values-en , para inglés americano
 values-en_US y para inglés británico values-en_GB . En español tendríamos
 values-es_ES y por ejemplo `values-es_AR" para español de Argentina.

Versión de la API

Hay algunos Views, valores, temas, etc. que sólo están disponibles a partir de cierta versión de la API
de Android y hay que tener cuidado de no intentar usarlos si el dispositivo en el que se usa la app no
tiene dicha versión.

Así por ejemplo, si sabemos que el tema Theme.Holo.Dark necesita Android 4.0 o superior (API
14) y queremos mantener la compatibilidad con Android 2.3.3 (API 10), por ejemplo, necesitaremos
crear:

         values : aquí irían los recursos de APIs 8 a 13 y comunes a todas las APIs.
         values-v14 : aquí irían los recursos propios de las APIs 14 y mayores.

Si por ejemplo quisiéramos usar el tema Theme.Material.Light , de Android 5.0 (API 21)
tendríamos que crear otra carpeta values-v21 con sus respectivos values.

Como se ha dicho, esto es para mantener compatibilidad. Si quisiéramos hacer una app que
funcionase sólo en Android 5.0 y superiores no sería necesario usar el modificador de API, con la
carpeta por defecto nos valdría.

Tipos de recursos:

Animaciones:

Tienen la siguiente forma:

Un set es un conjunto de de animaciones, que puede tener un interpolator (una forma de regular la
velocidad a la que se ejecutan las partes de la animación) y una serie de animaciones de los tipos:

    alpha: cambio de opacidad, 0 es invisible (pero aún se puede tocar) y 1 totalmente visible.
    scale: cambiar el ancho y el alto (X e Y), el pivot es desde qué punto de la View se inicia la
    animación, si pusiésemos 0.5 en pivotX y pivotY se iniciaría desde el centro.
    translate: cambiar la posición en pantalla de la View.
    rotate: rotar cierta cantidad de grados la View.

Todas las animaciones además tienen los valores:

    duration: duración en ms de la animación (1000ms -> 1s).
    fillBefore | fillAfter: indica si se debe animar y además cambiar los valores de la View, pues es
    posible animar y que el cambio sólo sea estético pero no llegue al código, de forma que por
    ejemplo después de desplazar un View pinchas en la antigua posición, aún salte el evento de
    click.
             fillBefore : aplicar el cambio de valores antes de empezar la animación. Debe
         acompañarse de fillEnabled="true" para que tenga efecto.
             fillAfter : aplicar el cambio de valores al finalizar la animación (no es necesario
             fillEnabled ).

Las animaciones se pueden cargar en código con:

 Animation translateAnim = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump)
 miView.startAnimation(translatAnim);

Drawables

Como se ha dicho antes, un Drawable puede ser:

    Un fichero de imagen.
    Un color.
    Un XML que combine imágenes, colores, formas, etc.
    Una serie de drawables combinados.
    Un selector con distintos valores para los distintos estados de una View.

Vamos a ver cómo se define por ejemplo un botón con relieve:
Este botón podría verse así al aplicarlo como android:background a una View:

El esquema es el siguiente:

 * Lista de capas:
     |-> Item:
     |    |
     |    |->Shape, Bitmap, etc.
     |    |    |->Propiedades

Si quisiésemos hacer un selector para que el botón se animara al pulsarlo:
Este selector toma los posibles valores de los estados de View (pressed, selected, disabled, etc.) y
asigna un drawable a cada uno de ellos, de forma que cuando se pulse o se desactive, el drawable
que se dibuje cambiará.

Este selector podría llamarse por ejemplo numpad_button y se podría seleccionar mediante
 @drawable/numpad_button .

Menús

Los menús se crean mediante archivos XML también.

Este menú tendría 2 acciones, una con ID new_game y otra con ID help. Aunque ambos tendrían
iconos, normalmente sólo se mostraría el primero.

Esto se controla con android:showAsAction . Como vemos, el primero usa "ifRoom", es decir,
"si queda espacio".

Este menú podría verse similar al siguiente:
Donde los items con showAsAction activado serían los iconos y el resto estaría en el menú
desplegable.

Raw
Aquí van el resto de recursos que no tienen cabida en ninguno de los apartados. Si por ejemplo
quisiéramos cargar un MP3 podríamos hacerlo así:

 InputStream streamDatos = getResources().openRawResource(R.raw.mi_cancion);

Lo cual nos abriría una puerta a los datos del archivo "mi_cancion.mp3" guardado en res/raw .

Values

Dentro de values podemos encontrar:

Arrays:

Son arrays o listas de recursos:

     Madrid
     Barcelona
   
      544
      797
    
Pueden cargarse con:

 String[] ciudades = getResources.getStringArray(R.array.ciudades);
 int[] distancias = getResources.getIntArray(R.array.distancia_a_almeria);

O asignarse a un ListView o Spinner con:

 android:entries="@arrays/ciudades"

Colores:

Nombres asignados a colores para su reutilización:

    #FF33B5E5
    #FFAA66CC
    #FF99CC00
    #FFFFBB33
#FFFF4444
    #FF0099CC
    #FF9933CC
    #FF669900
    #FFFF8800
    #FFCC0000

Pueden cargarse como:

 int azul = getResources.getColor(R.color.blue);

O asignarse como un drawable:

 android:background="@color/blue"

Dimensiones:

Tamaños, ya sea de márgenes, anchos, altos, tamaños de fuentes...

   56dp
   32dp
 
Se cargan con:

 int progressSize = (int) getResources().getDimension(R.dimen.indterminate_progress_si

O usarse como una dimensión más:

 android:layout_width="@dimen/width_view_principal"
 android:marginTop="@dimen/margen_global"

Strings:

Cadenas de texto:

   Hello!
 
Pueden cargarse mediante:

 String hello = getString(R.string.hello);
// O también
 hello = getResources.getString(R.string.hello);

Y pueden usarse con la propiedad android:text="@string/mi_string" .

Temas y estilos:

Los estilos o styles en Android son similares a los estilos de CSS, se aplican a un elemento para no
tener que definirlo todo cada vez en el xml o para elementos que tienen configuraciones comunes.

Así por ejemplo, si nuestra app tiene un tema rojo y queremos que todos los botones sean rojos con el
texto en blanco podemos definir:

     20sp
     #fff
     #cc0000
   
Como veis le hemos puesto como estilo padre el del botón por defecto de Android para que herede
todos sus estilos por defecto y hemos sobreescrito el tamaño del texto, su color y el fondo del botón.

Para aplicar este estilo usaríamos:

Si ahora quisiéramos un botón rojo con el texto enorme podríamos crear:

     40sp
   
De esta forma tendríamos los mismos estilos que en RedButton, pero con el texto mucho más grande.

Temas:

Los temas son estilos que se aplican a una Activity o incluso a la aplicación entera. Para ello deben de
tener como parent un tema por defecto de los de Android y pueden cambiar sus valores mediante
items.

Por ejemplo, podemos tener el siguiente tema:
@color/green_color
   @color/green_color
 
Que nos permitiría cambiar el color de fondo de la ventana por un color verde.

Este tema lo aplicaríamos en el AndroidManifest.xml :

Assets

Los Assets funcionan de forma similar a los raw pero permiten tener acceso al archivo como tal,
pudiendo copiarlo, borrarlo, listarlo, etc.

Suelen usarse para guardar archivos relacionados con web para mostar en WebView y similares.

AndroidManifest.xml

El Android Manifest es un archivo XML que define puntos importantes de la app como por ejemplo:

     Permisos que usa la aplicación.
     Elementos que la componen.
     Dispositivos soportados.
     Características necesarias para su ejecución (cámara, bluetooth, gps...).
android:label="@string/app_name">
         
         . . . 
      
         . . . 
      
Este Manifest, por ejemplo:

    Tiene como paquete principal del proyecto com.example .
    Usa el permiso de Internet, sin el cual la aplicación se cerraría al intentar conectar a la red.
    Necesita que el dispositivo tenga cámara obligatoriamente.
    No soporta pantallas grandes (large).
    Tiene un icono, un label (o nombre) y un tema para la app y permite que se haga copia de
    seguridad de la misma.
    Tiene una activity que aparece en el Launcher (inicio del teléfono) debido a su intent-filter con
    category android.intent.category.LAUNCHER .
    Tiene un Service que hace trabajo de fondo.
    Tiene un BroadcastReceiver que responde a eventos del sistema según su intent-filter.
También puede leer