martes, 29 de mayo de 2012

Programación Android: Recursos – Usando recursos


A todos los recursos que colocamos en las subcarpetas de ./res/ se puede acceder a través de la clase R de nuestro proyecto.
Esta clase R la genera el comando aapt en una pasada anterior a la compilación
(Eclipse, por defecto, la va generando continuamente conforme cambiamos los
recursos). Contiene todos los identificadores de recursos para poder referenciarlos.
Al igual que la carpeta “res”, la clase R se organiza en subclases, así por ejemplo el icono que colocamos en ./res/drawable/icon tiene su correspondencia en
R.drawable.icon (que es un identificador estático de tipo int y sirve para acceder
al recurso).
Así entonces los ID de recurso están compuestos de:
Clase R que contienen todos los recursos.
Subclase de recurso, cada grupo tiene la suya (drawable, string, style, layout…).
Nombre del recurso que, según el tipo, será: el nombre del fichero sin la extensión o el atributo xml “android:name” si es un valor sencillo (cadena, estilo, etc.).
Tenemos dos formas de acceder a los recursos definidos en la clase R:
En el código, accediendo a las propiedades de la clase R directamente
(R.string.nombre).
En los ficheros XML, usando una notación especial: @grupo_recursos/
nombre_recurso, es decir, el recurso anterior se accedería con @string/nombre.
Si lo que queremos es acceder a un recurso definido por el sistema antepondremos el prefijo android:
  • Desde el código: android.R.layout.simple_list_item_1.
  • En los ficheros XML: @android:layout/simple_list_item_1.

 Empezaremos por un recurso muy común, los string:

Recursos string

Android permite definir strings en uno o más archivos XML de recursos. Estos archivos están bajo el directorio ./res/values. El nombre del archivo XML para este tipo de recurso puede ser cualquiera, pero por convención se suele llamar strings.xml. Veamos un ejemplo de este fichero:
< ?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="hello">Hello</string>
   <string name="app_name">Hello app_name</string>
</resources>
Cuando este archivo se crea o modifica, el plugin ADT de eclipse automáticamente creará o actualizará una clase java de nuestra aplicación llamada R.java alojada en el directorio ./gen, que contiene los IDs únicos para las dos cadenas que acabamos de crear.
Para el fichero strings.xml que acabamos de crear, tendremos lo siguiente en la clase R:
package nombre.de.nuestro.paquete;
 
public final class R {
   //.. otras entradas dependiendo de tu proyecto y aplicación
 
   public static final class string {
      //.. otras entradas dependiendo de tu proyecto y aplicación
      public static final int app_name=0x7f040001;
      public static final int hello=0x7f040000;
      //.. otras entradas dependiendo de tu proyecto y aplicación
   }
   //.. otras entradas dependiendo de tu proyecto y aplicación
}
Como vemos como primero R.java define una clase principal en el paquete raiz: public final class R. Depues, define una clase interna llamada public static final class string. R.java crea esta clase estática interna como espacio de nombres para guardar los IDs de los recursos string.
La definición de los dos public static final int llamados app_name y hello son los IDs de los recursos que representan nuestras cadenas de texto. Podemos usar estos IDs en cualquier lugar de nuestro código mediante R.string.hello o R.string.app_name
La estructura del fichero string.xml es muy fácil de seguir. Tenemos un elemento raiz llamado , seguido por uno o más elementos hijos . Cada elemento tiene una propiedad llamada name que será la que usará como identificador R.java.
Para comprobar que se permiten varios recursos de string en el directorio values, vamos a crear otro fichero llamado strings1.xml con lo siguiente:
< ?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="hello1">Hello</string>
   <string name="app_name1">Hello app_name</string>
</resources>
Ahora, el plugin ADT de eclipse se encargará de actualizar el fichero R.java, que contendrá lo siguiente:
package nombre.de.nuestro.paquete;
 
public final class R {
   //.. otras entradas dependiendo de tu proyecto y aplicación
 
   public static final class string {
      //.. otras entradas dependiendo de tu proyecto y aplicación
      public static final int app_name=0x7f040001;
      public static final int hello=0x7f040000;
      public static final int app_name1=0x7f040006;
      public static final int hello1=0x7f040005;
      //.. otras entradas dependiendo de tu proyecto y aplicación
   }
   //.. otras entradas dependiendo de tu proyecto y aplicación
}

Referenciando atributos de estilo

Cuando aplicamos estilos a nuestros layout puede interesarnos acceder a un
atributo concreto de un estilo, para eso tenemos una sintaxis específica que
podemos usar en nuestros XML:
?[:][/]
Así por ejemplo si queremos colocar un texto pequeño usaremos:
?android:attr.textAppearanceSmall
Si queremos, también podemos utilizar nuestros propios atributos.
Primero lo definimos con un tag “attr”·dentro de ./res/values/attr.xml.
< ?xml version="1.0" encoding="utf-8"?>
<resources>
     <attr name="cabecera" format="reference" />
</resources>
Ahora ya podemos usar esa propiedad en nuestros estilos:
Primero definimos un estilo de texto llamado “TituloRojo”, y luego lo aplicamos
al atributo que hemos creado llamado “Cabecera”. Obsérvese que como es un
atributo propio, no usamos el espacio de nombres “android:”.
Si luego quisiéramos acceder a este atributo al definir un layout podríamos usar
la sintaxis mencionada:
./res/layout/milayout
< ?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent">
<textview android:layout_width="fill_parent
     android:layout_height="fill_parent"
     android:text="No hay datos disponibles"
     style="?attr/cabecera" />
</framelayout>
./res/values/style.xml

< ?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MiTema" parent=
     "@android:style/Theme.Light">
     <item name="android:windowBackground">
     @drawable/fondo</item>
     <item name="cabecera">
     @style/TituloRojo</item>
</style>
<style name="TituloRojo"
     parent="@android:style/TextAppearance.Large">
     <item name="android:textColor">#FF0000</item>
     <item name="android:textStyle">bold</item>
</style>
</resources>

1 comentario: