¿Recién te has iniciado al mundo del Desarrollo Android y ya te topaste con la carpeta res?
¿Sabías que dentro de ella se ubican los recursos en Android?
Seguramente ya habrás utilizado sin darte cuenta los recursos que vienen por defecto al crear un nuevo proyecto en Android Studio.
Sin embargo es importante conocer la naturaleza, funcionamiento y ventajas que tiene usar por separado archivos para imágenes, strings, estilos, etc.
Sigue leyendo y aprenderás sobre los tipos de recursos que existen, la funcionalidad del archivo R.java, creación de recursos alternativos, acceso de recursos a través de XML y Java, obtención de valores y el uso de los recursos del sistema.
¿Qué Son Los Recursos En Android?
Los recursos son archivos o datos externos que soportan el comportamiento de nuestra aplicación Android. Con ello me refiero a imágenes, strings, colores, estilos, etc.
Formalmente en un proyecto, estos elementos se encuentran en la carpeta src/main/res. Allí encontrarás subdirectorios que agrupan los diferentes tipos de recursos.
La idea del uso de recursos es dividir el código de tu app para mantener independencia. Todo con el fin de agregar variaciones de los archivos para adaptar la aplicación a diferentes tipos de pantallas, idiomas, versiones, dimensiones, configuraciones de orientación, etc.
Por ejemplo…
No es lo mismo el espacio de un teléfono móvil a una tableta. Sin embargo se pueden crear variaciones de los recursos para que la aplicación se adapte a la densidad de pantalla de cada uno.
Tipos De Recursos
Los grupos de recursos se dividen en subdirectorios. Cada uno de ellos contiene archivos que cumplen una función específica dentro de la aplicación. Debes respetar esta estructura de documentos para no tener problemas en la ejecución.
La siguiente es una tabla de la mayoría de los tipos de recursos que podemos crear:
Nombre del subdirectorio | Contenido |
---|---|
animator/ |
Alberga archivos XML con animaciones de propiedades para objetos. |
anim/ |
Contiene archivos XML que representan animaciones especiales para views. |
color/ |
Aquí encontrarás archivos XML con definiciones de listas de estados de color (Color State List). Estas listas determinan el color de un componente dependiendo del estado en que se encuentre. |
drawable/ |
Recursos gráficos que puedan ser proyectados en pantalla. Generalmente encontrarás archivos de imagen como .png, .jpg o .gif, sin embargo es posible usar otros como: archivos nine-patch, listas de estado, drawables con múltiples niveles, drawables con figuras 2D definidas en XML, y muchas más. |
mipmap/ |
Contiene el icono de la aplicación para evitar distorsión entre varias densidades de pantalla. |
layout/ |
Archivos XML que contienen definiciones de la interfaz de usuario. |
menu/ |
Archivos XML que establecen las características para los menús usados en la interfaz. Normalmente contienen definiciones sobre los ítems albergados en un menú y las agrupaciones entre ellos. |
raw/ |
Almacena aquí todos aquellos archivos que deseas leer directamente como un flujo de caracteres estándar (InputStream ). |
values/ |
Archivos XML que contienen datos simples como enteros, strings, booleanos, colores. Puedes agrupar estos elementos en las siguientes convenciones de archivos:
|
xml/ |
Contiene archivos XML con definiciones especiales requeridas en acciones con el framework de Android. O para usos que requieras en tus requerimientos, como parsear una estructura XML directamente en la aplicación. |
Recursos Alternativos En Android
Un recurso alternativo es una variación de un recurso, que se ajusta a una característica de configuración en el dispositivo móvil donde se ejecuta la aplicación.
Esto se logra a través de una tabla de calificadores creada por Google que estandariza todas las configuraciones posibles que se puedan presentar.
Un calificador es un mecanismo gramatical que especifica el propósito de un recurso. Su sintaxis es la siguiente:
<nombre_recurso>-<calificador>
De seguro ya vas comprendiendo un poco porque al crear un nuevo proyecto en Android Studio vienen varias carpetas para el recurso mipmap.
Esto se debe a que cada variación contiene un calificador para especificarle a la aplicación que al momento de variar la densidad de pantalla, escoja el recurso que se ajuste a esta configuración.
Por ejemplo mipmap-hdpi contendrá la variación del recurso ic_launcher.png para aquellos dispositivos con densidades de pantalla altas (~240dpi). Esta condición es especificada por el calificador hdpi.
Esto significa que la imagen debe estar especialmente creada para ajustarse a esta densidad. Así mismo, las demás imágenes deben ser creadas a la medida de su calificador.
Todas las variaciones responden a un mismo identificador, por eso tienen el mismo nombre de archivo "ic_launcher.png"
.
Precedencia de calificadores— Los calificadores tienen orden precedencia, es decir, para usar más de un calificador en un recurso es necesario ubicar primero los calificadores con mayor importancia. Si se desobedece esa secuencia, habrá calificadores que no tengan efecto.
La siguiente tabla muestra los calificadores existentes en orden de precedencia.
Calificador | Valores/Sintaxis | Ejemplo/Definición |
---|---|---|
Código Móvil del País | mccxxx-mncxxx |
mcc732-mnc101 (Operador Claro en Colombia) |
Idioma y región | xx-rXX |
es-rCO (Español en Colombia) |
Dirección del layout | ldrtl, ldrtl |
ldrtl (lectura de derecha a izquierda), ldrtl (lectura de izquierda a derecha) |
Ancho mínimo de la pantalla | sw<N>dp |
sw480dp , sw240dp |
Ancho disponible | w<N>dp |
w600dp , w1024dp |
Altura disponible | h<N>dp |
h180dp |
Tamaño de la pantalla | small, normal, large, xlarge |
|
Aspecto de la pantalla | long, notlong |
|
Orientación de la pantalla | port, land |
|
Modo UI | car, desk, television, appliance, watch |
|
Modo nocturno | night, notnight |
|
Densidad de pantalla | ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi nodpi tvdpi |
|
Tipo de pantalla táctil | notouch finger |
|
Disponibilidad del teclado | keysexposed keyshidden keyssoft |
|
Método primario de entrada de texto | nokeys qwerty 12key |
|
Disponibilidad de las teclas de navegación | navexposed navhidden |
|
Método primario de navegación no táctil. | nonav dpad trackball wheel |
|
Versión de Android | vN |
v17 , v21 |
Para asociar múltiples calificadores a un recurso es necesario que los separes por guiones siguiendo el orden anterior.
Por ejemplo…
Declaremos la variación del subdirectorio values para la dirección de lectura izquierda-derecha y orientada al idioma inglés.
values-ldrtl-en/
Es sencillo, solo buscamos el orden de ambas características en la tabla. Primero va el sentido de lectura, así lo ubicamos separado por guion. Luego sigue el idioma, por lo que anteponemos un nuevo guion y añadimos el indicador en
en segunda posición.
Crear Recursos En Android Studio
Para crear nuevos recursos en Android debes situarte en la carpeta res y luego añadir un nuevo subdirectorio o archivo de recurso, dependiendo del caso.
Por ejemplo, si deseas crear un subdirectorio para recursos tipo raw, entonces presionas click derecho en la carpeta res, selecciona New y luego eliges Android resource directory.
Esto abrirá un asistente que te permite seleccionar el tipo de recurso y aquellos calificadores que deseas incluirle.
Por ejemplo, si deseáramos añadir un calificador para los recursos raw orientados a idioma inglés, seleccionamos el calificador Locale. Este desplegará una lista para elegir el idioma y las ubicaciones. Prueba elegir idioma inglés y ubicación Estados Unidos.
Al confirmar, tendremos nuestro nuevo subdirectorio en la carpeta res.
Para agregar un nuevo archivo de recurso es el mismo procedimiento. Presionas click derecho, dirígete a la opción New en el subdirectorio deseado y luego asignas un nombre u otros campos que se requieran, dependiendo del tipo de recurso.
Por ejemplo… al intentar crear un nuevo archivo dentro de res/values nos exigirán el nombre.
Acceder A Los Recursos En Android
Hasta ahora ya sabemos cómo agrupar los tipos de recursos y definir archivos XML para algunos de ellos.
Lo que sigue es comprender el acceso a sus valores desde el proyecto. Los recursos pueden ser accedidos en el código Java o en el código XML.
Para obtener la referencia de un recurso es necesario que se le asigne un identificador que lo diferencie y le indique al programador donde se encuentre.
Cada identificador se ubica en una clase llamada R
a través de una constante entera. Esta clase es generada automáticamente por una herramienta del SDK llamada appt, por lo que no es recomendable editarlo manualmente.
Cada tipo de recurso existente dentro de la carpeta res es una clase anidada estática del archivo R.java.
Por ejemplo, el subdirectorio drawable puede ser accedido como R.drawable
.
Ahora, si deseas obtener el identificador de un recurso, entonces usas el operador punto para acceder a los miembros de cada clase interna.
Por ejemplo, se tiene una imagen cuyo identificador es imagen_gato
. Para acceder a su contenido solo navegas de la siguiente forma R.drawable.imagen_gato
.
El archivo R.java en un proyecto tendría un aspecto similar al siguiente:
Acceder a los recursos desde Java— Ya vimos de forma general como podríamos obtener el ID de un recurso con la clase R
. La sintaxis formal de acceso es la siguiente:
[<nombre_paquete>.]R.<tipo_recurso>.<nombre_recurso>
Donde,
[<nombre_paquete>.]
es el nombre del paquete donde se encuentran alojados los recursos. No uses ninguno, si te estás refiriendo al paquete local.<tipo_recurso>
es una de las agrupaciones de recursos como por ejemploxml
.<nombre_recurso>
es el nombre del archivo asignado o el identificador de un elemento.
Existen muchas formas de implementar las referencias de los recursos dependiendo de la situación.
Por ejemplo…
1. Uno de los primeros usos que verás al crear un nuevo proyecto en Android Studio es la asignación de un layout a una actividad.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }En este caso se usa el método
setContentView()
para indicar el layout que dará forma visual a la actividad. El ejemplo muestra que será el recursoR.layout.activity_main
, el cual representa al archivo activity_main.xml guardado en el subdirectorio layout.2. Otro ejemplo lo vemos al momento de asignar un recurso de menú para crear la action bar de una actividad.
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; }En este caso se pasa el ID del archivo menu_main.xml alojado en el subdirectorio menu. Es por eso que usamos la referencia
R.menu.menu_main
.3. También podemos usar recursos al momento de asignar el contenido a un ImageView (elemento que representa imágenes en la pantalla).
ImageView imagen = (ImageView) findViewById(R.id.imagen); imagen.setImageResource(R.drawable.avatar);Primero se obtiene el image view a través del método
findViewById()
y luego se le asigna el identificador del drawableR.drawable.avatar
con el métodosetImageResource()
.4. Tal vez uno de los más populares sea asignar un string a un
TextView
con el métodosetText()
, el cuál recibe el identificador de un recurso tipo texto.TextView titulo = (TextView) findViewById(R.id.titulo); titulo.setText(R.string.texto_titulo);
Por el momento nos estamos refiriendo a la referencia de los recursos, pero…
¿Cómo obtener los valores directamente?
La respuesta está en la clase Resources
.
Este elemento representa la ubicación de los recursos y su contenido. Podemos obtener una instancia dentro de una actividad con el método getResources()
.
A través de ella podemos acceder a los valores de cualquier tipo de recurso. Todo a través de sus métodos get*()
.
Si deseas obtener un recurso tipo string
, entonces invocas a getString()
, el cual recibe como parámetro el ID del recurso:
Resources resources = getResources(); String appName = resources.getString(R.string.app_name);
De forma similar, podemos obtener el valor entero de un recurso tipo color:
Resources resources = getResources(); int color = resources.getColor(R.color.colorAzul);
Para los arrays de strings también existe su correspondiente método:
Resources res = getResources(); String[] campeones_adc = res.getStringArray(R.array.campeones_adc);
Acceder a los recursos desde XML— Esta forma de referencia se da cuando dentro de un recurso definido en un archivo XML necesitamos usar el valor de otro recurso.
Por ejemplo, cuando a un componente <TextView>
dentro de un layout le asignamos el valor de un string definido en el archivo strings.xml.
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/titulo_texto" />
La forma en que se asigna el ID depende de la siguiente sintaxis:
@[<nombre_paquete>:]<tipo_recurso>/<nombre_recurso>
Donde,
@[<nombre_paquete>:]
se refiere al paquete java donde está alojado el recurso (no pones nada si son los recursos locales).<tipo_recurso>
es el tipo de recurso representado como clase anidada en R.java. Por ejemplostring
.<nombre_recurso>
es el nombre del archivo sin extensión o el valor del atributoandroid:name
del componente.
Veamos algunos ejemplos:
1. Supón que dentro del recuro values/dimens.xml defines el padding de los textos de la siguiente forma.
dimens.xml
<resources> <dimen name="padding_textos">16dp</dimen> </resources>Ahora decides utilizarlo en el atributo
android:padding
de un texto. Para ello solo usas la sintaxis vista anteriormente refiriéndote a los recursos de tipodimen
.<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Texto" android:padding="@dimen/padding_textos"/>Cada vez que intentes asignar un recurso en un atributo, Android Studio te ayudará con una búsqueda emergente para una selección más rápida.
2. Dentro del tema de la aplicación también es posible asignar valores de recursos. Supón que asignarás un azul índigo como color primario al tema. Para ello declaras el valor en tu recurso values/colors.xml.
<resources> <color name="colorPrimario">#3F51B5</color> </resources>Luego estableces el atributo
colorPrimary
con este recurso.<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimario</item> </style> </resources>
Acceder a los recursos del sistema— Android contiene en su framework varias constantes de recursos que nos permitirán acceder a estilos, tamaños, colores, layouts, etc.
En ocasiones es de utilidad usarlos para evitar la declaración de elementos que ya existen. Para usarlos debemos referirnos al paquete android
en cada acceso que realicemos.
Un buen ejemplo sería el uso de colores predeterminados.
<resources> <style name="AppTheme" parent="@android:style/Theme"> <item name="android:windowBackground">@android:color/white</item> </style> </resources>
El anterior estilo asigna el color blanco almacenado en el paquete del sistema al background de las actividades de la aplicación.
Otro ejemplo sería al momento de tomar las acciones del Up Button de una actividad dentro del método onOptionsItemSelected()
. Este elemento está predeterminado por el sistema ya que nosotros no lo construimos, sin embargo podemos recibir sus eventos con el identificador android.R.id.home
:
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { case android.R.id.home: // Acciones return true; } return super.onOptionsItemSelected(item); }
Ejemplos De Recursos
A continuación veremos de forma general como se crean algunos archivos de recurso en definición XML que pertenecen al subdirectorio values y son de uso frecuente.
Existen tipos de recursos que requieren explicaciones más detalladas como los estilos y los layouts, por lo que serán tratados individualmente en artículos separados.
Recursos de colores en Android— Todo archivo XML para recursos debe contener un nodo raíz del tipo <resources>
.
Dentro de un archivo de colores (colors.xml) los elementos deben ser declarados con la etiqueta <color>
. Debes asignar un nombre único con el atributo name
y su contenido es un color en forma hexadecimal que empieza por el símbolo numeral '#'
.
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorAzul">#0057ff</color> <color name="colorRojo">#ff0044</color> </resources>
El anterior código contiene dos recursos de color.
Android Studio te permite modificar el color a través de un asistente que se inicia al seleccionar el recuadro de color. Este se encuentra justo al lado izquierdo.
El asistente te permitirá personalizar al máximo el color que deseas. Desde seleccionar manualmente la cantidad de azul, rojo, verde y alfa, hasta copiar el color de un pixel en tu escritorio.
Recursos strings en Android— Los recursos de tipo strings nos permiten almacenar valores que representan texto en nuestra aplicación.
Son de gran utilidad, ya que puedes crear variaciones de idioma para cada recurso string.
Como ya has visto, el archivo values/strings.xml ha sido designado por convención para contener este tipo de recursos.
Los elementos más comunes son strings simples con un solo contenido y arrays de strings que asocian varios elementos a un solo nombre.
Los strings simples se definen con la etiqueta <string>
. Para darle un identificador usa el atributo name
y asigna un nombre distintivo.
<string name="nombre_string">texto_string</string>
Los arrays se declaran con <string-array>
y asignarles un nombre con el atributo name
. Cada elemento irá en su interior declarado con un elemento <item>
y su contenido será el texto que representa.
Veamos un ejemplo…
<resources> <!-- strings de contenido simple --> <string name="app_name">Mis Pruebas</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> <!-- Array de strings --> <string-array name="campeones_adc"> <item>Caitlyn</item> <item>Draven</item> <item>Jinx</item> <item>Varus</item> <item>Tristana</item> </string-array> </resources>
El anterior código muestra en la parte superior tres strings simples y en su parte inferior un array de strings con 5 ítems.
Una ventaja de usar Android Studio es que permite extraer textos hacia el archivo strings.xml a través de un asistente.
Si estuvieses definiendo un layout donde se encuentra el siguiente TextView
:
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Descripción de tareas"/>
Verás que el valor del atributo android:text
aparecerá marcado.
Este warning te está diciendo que sería buena idea extraer ese texto plano a un recurso string. Si presionas ALT+ENTER en esa posición, verás una lista de opciones. La que nos interesa es Extract string resource.
Si seleccionas esta opción se desplegará un asistente que nos permitirá trasladar el texto plano al archivo strings.xml con su respectivo identificador.
Una vez asignes el nombre, confirmas y ya tendrás tu nuevo recurso creado. Incluso el acceso por el text view será reemplazado.
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/descripcion_tareas"/>
Recursos para dimensiones en Android— Los recursos de dimensión permiten almacenar valores de medidas basadas en las características de la pantalla del dispositivo.
Por convención, las dimensiones se incluyen dentro del archivo res/dimens.xml para diferenciar su naturaleza. Cada recursos de dimensión se especifica con la etiqueta <dimen>
, a la cual debe añadírsele el atributo name
para diferenciar su existencia. En su contenido se indica un número junto a la unidad de medida a implementar.
<dimen name="nombre_dimension">dimension</dimen>
Los siguientes son los tipos de medida que puedes usar:
dp
: Medida basada en la densidad de pantalla, donde 1dp equivale a 1px. Esto significa que si la densidad varia, entonces las medidas en dp variarán dependiendo del factor. Esta unidad es muy útil para mantener el aspecto de los views en un layout.sp
: Es una medida similar a los dp, solo que su variación de proporciones se basa en el tamaño de la fuente del texto. Por lo que es buena opción usarla cuando definamos tamaños para los textos.pt
: Representa un factor de 1/72 puntos por pulgadas según el tamaño real de la pantalla.px
: Medida en pixeles de la pantalla. Debido a la gran variedad de tamaños de pantalla, no es recomendable adaptar los elementos basados en pixeles.mm
: Representa un milímetro basados en el tamaño real de la pantalla.in
: Medida en pulgadas basadas en el tamaño real de la pantalla.
El siguiente es un ejemplo donde se muestra una dimensión para el margen superior de un text view y su tamaño de fuente.
<resources> <dimen name="margen_superior">16dp</dimen> <dimen name="fuente_texto">24sp</dimen> </resources>
Conclusión
Este artículo te ha mostrado el uso de recursos en Android. Has aprendido como se agrupan según su naturaleza y de qué forma puedes crear variaciones alternativas.
Recuerda que es posible acceder a las referencias de los recursos tanto en otros recursos con formato XML así como en el código Java. También puedes obtener sus valores en el código a través de la clase Resources
, la cual gestiona todo el manejo de recursos.
Cada tipo de recurso trae consigo una serie de características especiales que puedes explorar mas a fondo. Si lo deseas, puedes seguir con el uso de estilos en Android.