Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Aplicaciones Android?
James Revelo agosto 1, 2014 Android Studio, Fundamentos 6 Comments
El día de hoy veremos cómo Desarrollar Aplicaciones Android. A lo largo de este artículo
estudiaremos la instalación del IDE Android Studiocomo entorno de desarrollo y que
configuraciones debemos llevar a cabo para un optimo funcionamiento.
Finalmente crearemos una pequeña aplicación estilo “Hello World” para comprobar el
funcionamiento del entorno de programación.
HERRAMIENTAS A UTILIZAR
Desarrollar para Android requiere un entorno basado en ciertas tecnologías integradas. En
primera instancia necesitamos las librerías y herramientas de los dueños, es decir,
el SDK(Software Delevelopment Kit) de Android. Con ello tendremos habilitado el camino
para generar nuevas aplicaciones en consola.
Como lenguaje de desarrollo usaremos Java para construir las aplicaciones. Además se usa
el metalenguaje XML para el diseño de interfaces a través de Parsing (Temas que veremos
más adelante).
También se usa un sistema de construcción automatizado llamado Gradle. Esta herramienta
emplea al javac (Java Compiler) para programar mediante “Scripting“ el funcionamiento
de la integración modular de nuestra aplicación. Si nunca has escuchado de ella no te
preocupes, más adelante hablaremos sobre los detalles importantes.
Una vez instalado el entorno completo debemos registrar una nueva variable de
entorno para indicarle a Android Studio, donde se aloja la máquina virtual. Para ello nos
dirigiremos a
Aparecerán dos Groupbox, uno llamado” Variables de usuario” y otro llamado “Variables
del Sistema”.
Pulsaremos el botón “Nueva…” en Variables del sistema y agregaremos una nueva variable
llamada JAVA_HOME. A esta nueva variable le asignaremos un String que represente la
ruta del directorio donde se encuentra instalado nuestro JDK.
La primera vez que ejecutas Android Studio, aparecerá un asistente de presentación. Por
ahora elegiremos la opción “New Project…” (Nuevo proyecto) para comprobar la
estabilidad del entorno.
Ahora seleccionaremos los Form Factors o Factores de Forma sobre los que se construirá el
proyecto. Por lo que seleccionamos “Phone and Tablet” (Teléfono y Tableta).
Adicionalmente debes escoger el SDK mínimo “Minimum SDK” que soportará tu
aplicación.
Por defecto viene seleccionada la última versión de la plataforma, que en este momento que
escribo el articulo es Android L Lollipop. Si el asistente no te deja cambiar la versión, no te
preocupes, luego veremos cómo acceder a versiones anteriores. Así que presiona “Next”.
El siguiente menú nos permite cual será la actividad principal de nuestra aplicación.
UnaActividad es un patrón de ejecución visual que se relacionará con las entradas
proporcionadas por el usuario para conseguir sus objetivos. Luego profundizaremos en este
concepto, por ahora elige Actividad en blanco (Blank Activity).
En este paso podemos cambiar el nombre de la actividad (Activity Name), el nombre del
Layout (Layout Name) relacionado y el titulo (Title). Si gustas deja los valores
predeterminados y luego entenderemos un poco más esta estructura. Finalmente
clickea“Finish” para comenzar.
Como ves, el entorno es muy acogedor, sencillo y con un diseño claro. Tenemos un espacio
al lado izquierdo que muestra la jerarquía de los proyectos (“Project“), un espacio de
trabajo en el centro y una previsualización (“Preview”) de la aplicación en la derecha.
Antes de proseguir ejecutáremos una herramienta llamada SDK Manager. Para ello presiona
el siguiente icono:
SDK Manager nos informa que complementos tenemos hasta el momento instalados en
nuestra maquina y cuáles no. Yo te recomendaría seleccionar todo lo que haya disponible e
instalarlo, ya que en algún momento necesitaras testear diferentes plataformas Android.
Obviamente se requerirá gran cantidad de tiempo de descarga para ejecutar esta tarea, pero
tendrás un robusto entorno de desarrollo.
Si no deseas instalar todo, entonces solo instala los complementos recomendados. Si usas un
Pc con arquitectura Intel entonces selecciona en la categoría “Extras“ el complemento Intel
x86 Emulator Accelerator (HAXM installer). Este plugin optimizará la ejecución de
nuestrosAVDs(Concepto que veremos en instantes).
Una vez terminada la instalación el siguiente paso que es abrir de nuevo Android
Studio y crear un nuevo Dispositivo Virtual Android (AVD).
Un AVD o Dispositivo Virtual Android es una máquina virtual que ejecuta la plataforma
Android seleccionada, para comprobar la funcionalidad de nuestra aplicación construida.
El SDK trae consigo una pequeña aplicación de gestión de AVDs llamada AVD
Manager. Así que la ejecutaremos para crear un nuevo dispositivo virtual.
Debido que aun no tenemos dispositivos creados veremos una lista vacía. Ahora dirígete a la
pestaña “Device Definitions”, donde encontraremos definiciones disponibles para un nuevo
dispositivo.
La lista de dispositivos es grande, hay varios modelos creados por Google para diferentes
gustos. Para este ejemplo he decidido usar un teléfono móvil genérico con resolución
QVGA. Te recomiendo elijas un teléfono que use baja cantidad de recursos en memoria si
tu computadora es limitada.
Una vez hayas seleccionado, presiona el botón “Create AVD…”:
Lo que sigue es configurar los requerimientos de hardware del AVD en él asistente que se
acaba de ejecutar. En él podemos modificar el nombre del dispositivo (AVD Name),
cambiar el modelo (Device), cambiar la versión de Android con que se ejecutará (Target).
También podemos elegir con que arquitectura de procesamiento móvil (CPU/ABI) se
ejecutará y muchas características más.
La versión de Android del proyecto debe ser la misma en el AVD. De lo contrario Android
Studio desplegará un error de incompatibilidad de SDKs.
Activa la opción “Hardware Keyboard Present“ si deseas que el AVD interprete el teclado
de nuestro PC como su teclado propio. Selecciona también la opción “Use Host GPU“ para
que tu tarjeta gráfica esté disponible en la ejecución.
Una vez configurado presiona OK. En seguida se desplegará un diálogo con un reporte que
confirma que atributos se le asignaron al AVD.
Luego del proceso de carga (dependiendo de tu hardware así mismo será el tiempo de
carga), Android estará ejecutándose en el AVD:
Si eres buen observador, verás que puedes seguir las acciones actuales del proceso de carga
viendo la herramienta logcat de la herramienta DDMS del SDK.
Como ves esta herramienta se encuentra en la barra inferior llamada “Android“. Si te fijas
bien además del logcat nos muestra que procesos están activos en el AVD (lado izquierdo),
como por ejemplo el calendario, servicio de correo, reloj, etc.
Una vez finalizada la instalación tendremos a nuestra aplicación desplegando ese tan deseado
mensaje “Hello World“.
Puedes confirmar la ejecución de tu aplicación en el DDMS.
Soy consciente de que en algunos equipos con recursos regulares la ejecución de un AVD
puede ser tediosa. Si es tu caso puedes seguir algunos de los siguientes consejos:
3.2 Presiona 7 veces la opción Número de compilación. Te darás cuenta que todo salió
bien porque aparecerá un Alert que dice “Ya eres un programador“.
3.3 Sigue los primeros pasos que indiqué arriba.
4. Ejecutar la aplicación y seleccionarlo como dispositivo de ejecución.
Luego dirígete al Group Box llamado Target Device y selecciona el Radio Button “USB
Device“.
Al aplicar los cambios ejecuta la aplicación, espera su instalación y listo:
Una vez seleccionada esta opción, tu PC comenzará a reconocer un canal más completo para
la comunicación USB. Solo espera que Windows busque automáticamente el controlador y
lo instale.
Inmediatamente Android Studio reconocerá tu dispositivo.
Introducción A Java Para
Desarrollo Android
James Revelo agosto 8, 2015 Fundamentos 10 Comments
En este artículo repasarás los conceptos básicos del lenguaje Java con el fin de recordar y
fortalecer tus conocimientos.
Esto permitirá acercarte mucho más al Desarrollo Android y evitar que te pierdas en
algunostutoriales donde se usan funcionalidades de Java.
Cabe aclarar que esta no es una guía para enseñarAlgoritmia o un curso profundo de
programación Java. Simplemente quiero resaltar aquellos aspectos que serán de vital
importancia estudiar antes de crear aplicaciones Android.
Asumiré que ya tienes instalado el JDK y que conoces las potencialidades de la máquina
virtual de Java y como esta permite ejecutar secuencias en gran variedad de plataformas.
Recrearemos el famoso ejemplo “Hello World”, donde el objetivo principal es imprimir una
sola línea de caracteres en la consola. Para ello ve a un editor de texto como bloc de notas y
pega el siguiente código.
Ahora guarda el archivo con extensión .java con el nombre de “PruebaJava.java” en algún
directorio de fácil localización.
Ahora abre tu consola de comandos y escribe la siguiente línea para compilar el archivo:
javac PruebaJava.java
Con ello, ya está listo el archivo PruebaJava.class. Lo que significa que ya puedes ejecutar
el programa con el comando:
java PruebaJava
"Recordando Java..."
Este ejemplo muestra la creación de una clase sencilla con un método main(). Recuerda que
este método actúa como el punto de inicio de la aplicación. En él se ejecutan las acciones
fundamentales de la app. Si no lo incluyeras, la ejecución arrojaría un error.
La impresión del texto se logra con el método System.out.println(), solo incluyes el
texto que deseas proyectar encerrado en comillas dobles (" ").
2. PAQUETES DE CLASES
Los paquetes son estructuras de directorios que agrupan tus recursos Java para evitar
colisiones de nombres. Por ejemplo, si tuvieses una clase en el
paquetecom.herprogramacion.modelo.Archivo no habría problema en tener una clase
con el mismo nombre en com.herprogramacion.utilidades.Archivo.
Como ves, esta división aísla las características de ambas clases y así puedes nombrarlas
igual.
▪ El nombre de los paquetes debe ser en minúsculas para evitar conflictos con los nombres de las clases,
las cuales usan notación CamelCase. Nada de nombres comoCom.FinaNzas.CuENTAs.
▪ Solamente los paquetes exclusivos del lenguaje pueden comenzar con la palabra java ojavax.
▪ Asegura que la estructura de los paquetes sean únicos. Generalmente se usa como convención el
dominio de internet de las compañías a la inversa. En mi caso seríacom.hermosaprogramacion.
▪ Existen casos donde el nombre de la compañía no funciona. Por ejemplo: cuando el dominio usado
contiene una palabra reservada; cuando hay caracteres especiales como'-'; o si el paquete comienza
con dígitos numéricos. Para solucionarlo antepón un guion bajo para complementar '_'.
Los comentarios son bloques de texto significativo que serán ignorados por el compilador
Java. Al igual que otros lenguajes como C++, Php, Javascript, etc., estos permiten detallar
las características de tu código, con el fin de comprender su funcionamiento por toda persona
interesada en el desarrollo.
Es posible realizar comentarios de línea simple, donde solo se escribe una línea comentada a
través de barras verticales //.
/*
Este conjunto de instrucciones
genera una serie de números aleatorios
con el fin de sumar sus magnitudes
*/
Comentarios TODO en Java— Existen IDEs que permiten la creación de comentarios tipo
TODO. Con ellos se puede apuntar sobre el código tareas pendientes, preguntas sin resolver,
optimizaciones por realizar, etc.
Su propósito es dinamizar el código para que el programador recuerde eventos necesarios
que completarán el desarrollo rápidamente.
Por ejemplo…
En Android Studio los comentarios TODO se escriben de la forma //TODO:
[comentarios].
//TODO-james: Recuerda crear una prueba unitaria para el resultado del parsing para esta petición.
Se escribe la palabra TODO( en Español sería “Por hacer”) y luego especificas la acción. Si
deseas añades el nombre de la persona encargada.
La ventaja es que podrás ver en forma de lista todos los comentarios TODO dentro del
proyecto o el archivo actual.
4. TIPOS DE DATOS PRIMITIVOS
Tipo de
dato Descripción
byte Representa a un número de 8 bits, cuyo rango se encuentra entre -128 y 127
short Número entero de 16 bits, cuyo rango se encuentra entre -37768 y 32762
int Es capaz de contener un número entero con signo de 32 bits, cuyo rango es {-231, 231-1}
long Representa un número entero de 64 bits con signo, con rango de {-263, 263-1}
Tipo de dato para el manejo de números de punto flotante con una precisión sencilla de
float 32bits
double Tipo de dato para el manejo de números de punto flotante con un doble precisión a 64bits
Los arrays son objetos que contienen múltiples valores de un solo tipo. La cantidad de
elementos que contenga debe ser predefinida para que sea posible relacionar un índice a la
posición.
PruebaArray.java
class PruebaArray {
public static void main(String[] args) {
// Declaración del array
int[] arrayDeEnteros;
arrayDeEnteros[0] = 1;
arrayDeEnteros[1] = 3;
arrayDeEnteros[2] = 5;
arrayDeEnteros[3] = 7;
arrayDeEnteros[4] = 9;
System.out.println("arrayDeEnteros[0]: "
+ arrayDeEnteros[0]);
System.out.println("arrayDeEnteros[1]: "
+ arrayDeEnteros[1]);
System.out.println("arrayDeEnteros[0]: "
+ arrayDeEnteros[2]);
System.out.println("arrayDeEnteros[0]: "
+ arrayDeEnteros[3]);
System.out.println("arrayDeEnteros[0]: "
+ arrayDeEnteros[4]);
}
}
El resultado sería:
arrayDeEnteros[0]: 1
arrayDeEnteros[1]: 3
arrayDeEnteros[2]: 5
arrayDeEnteros[3]: 7
arrayDeEnteros[4]: 9
Como ves, tanto como la declaración y la inicialización del array requiere el uso de corchetes
para indicarle al compilador que será un array.
Si deseas obtener un valor del array en algún índice específico, entonces usa los corchetes
con el índice.
Incluso puedes declarar e inicializar en una sola línea. Los valores puedes asignarlos en
llaves, separando por comas.
6. USO DE OPERADORES
Los operadores son caracteres especiales para indicar la realización de una acción entre
variables.
multiplicativos * / %
aditivos + -
igualdad == !=
OR lógico ||
operador ternario ? :
asignación = += -= *= /= %= &= ^= |= <<= >>= >>>
Como ves, son una gran cantidad de opciones para computar tus datos. Por lo que puedes
realizar infinidad de tareas en tus aplicaciones.
7. ESTRUCTURAS DE DECISIÓN
Este tipo de sentencias se usan para desviar el flujo de ejecución de nuestros programas
basados en una condición establecida.
La estructura de decisión más simple es la sentencia if. Esta comprueba la veracidad de una
expresión para tomar decisiones. Si el valor es verdadero (true), entonces las acciones
definidas en su bloque de instrucciones.
if(expresionBooleana){
/*
Bloque de instrucciones a ejecutar si la evaluación es true
*/
}
Por ejemplo…
PruebaIf.java
class PruebaIf {
public static void main(String[] args) {
int a = 2;
int b = 3;
if(a+b >2){
System.out.println("La suma de ambos números es mayor que 2");
}
}
}
if(expresionBooleana){
/*
Bloque de instrucciones a ejecutar si la evaluación es true
*/
}else{
/*
Bloque de instrucciones para resultado adverso
*/
}
En el caso del ejemplo anterior, podríamos imprimir el mensaje contrario diciendo que el
resultado es menor.
if(a+b >2){
System.out.println("La suma de ambos números es mayor que 2");
}else{
System.out.println("La suma de ambos números es menor que 2");
}
switch(dato){
default:
// Acciones por defecto
case valor1:
// Acciones para valor 1
break;
case valor2:
// Acciones para valor 2
break;
//...
case valorN:
// Acciones para valor N
break;
}
switch (opcionElegida) {
default:
System.out.println("Opción elegida inválida");
break;
case "Ramiro Córdoba":
votosRamiroCordoba++;
break;
case "Susana Feliciano":
votosSusanaFeliciano++;
break;
case "Michael Stewart":
votosMichaelStewart++;
break;
case "Camila Rengifo":
votosCamilaRengifo++;
break;
case "Carlos Valdez":
votosCarlosValdez++;
break;
}
8. BUCLES EN JAVA
1. while: El bucle while ejecuta una y otra vez las mismas acciones mientras la condición
que se le ha establecido sea verdadera. Es la mejor opción, si no sabes con exactitud la
cantidad de iteraciones necesarias.
while(expresionBooleana){
/*
Bloque de instrucciones
*/
}
class PruebaWhile {
public static void main(String[] args) {
int suma = 0;
int contador = 1;
La suma es: 55
2. do-while: Este bucle es una variación del anterior. Además de repetir las instrucciones
mientras la condición sea verdadera, permite ejecutar la primera instrucción sin comprobar
la condición.
Para ello es necesario incluir las acciones dentro de la sentencia do y al final comprobar con
la sentencia while
do{
/*
Conjunto de instrucciones
*/
}
while (expresionBooleana);
EjemploDoWhile.java
class PruebaDoWhile {
public static void main(String[] args) {
int suma = 0;
int contador = 1;
do {
suma += contador;
contador++;
}
while (contador <= 10);
System.out.println("La suma es: " + suma);
}
}
3. for: El bucle for se encarga de repetir las instrucciones hasta la condición impuesta en sus
argumentos llegue a ser falsa. Es la mejor opción si sabes la cantidad de veces que deseas
ejecutar una condición.
▪ inicialización: Inicia la cuenta del bucle. Esto ocurre una sola vez.
▪ condicionDeParada: Expresión booleana que se relaciona con la inicialización para saber en qué
momento se detendrá el bucle.
▪ incremento: Expresión llamada al final de cada iteración, la cual permite incremento o decremento
de un valor.
A continuación traduzco el mismo ejemplo de la suma de números al bucle for.
PruebaFor.java
class PruebaFor {
public static void main(String[] args) {
int suma = 0;
for (int contador = 1; contador <= 10; contador++) {
suma += contador;
}
class PruebaForEach {
public static void main(String[] args) {
La variable entero es usada para guardar el elemento actual de la iteración. Esto permite que
imprimamos cada elemento del array .
Debido a que Java es un lenguaje orientado a objetos, es indispensable tener en claro cómo
usar clases y objetos.
Una clase es la abstración de las características de un objeto en particular. Esta define las
características (atributos) que posee y los comportamientos que tendrá (métodos).
En código, podemos comparar una clase con una especie de plantilla de la cual podemos
fabricar objetos.
Para declarar una clase debes usar la palabra reservada class y luego definir un bloque de
código que comprenda sus atributos y métodos.
public Si Si Si Si
protected Si Si Si No
sin modificador Si Si No No
private Si No No No
}
public class SubclaseDeFinal extends PruebaModificadorFinal{
Al hacerlo sobre un método, significa que las subclases de una superclase no pueden
sobrescribir este método.
Usar final con un atributo obliga a que asignes el valor en la declaración o en todos sus
constructores. El compilador lanzará un error si intentas asignar un valor en otro lugar o si
quieres asignar por segunda vez.
PruebaModificadorFinal() {
Los parámetros con final no se les pueden reasignar un valor distinto al que ya trae hacia el
método. Si se pasa por referencia un objeto, se asegura que no cambie la referencia, más no
el contenido del objeto.
Una variable local final debe ser inicializada obligatoriamente solo una vez. Intentar asignar
por segunda vez produciría un error.
PruebaModificadorFinal() {
sumarNumero(3);
}
Por ejemplo…
Se tiene la clase Enemigo, la cual tiene atributos como la cantidad de vida, maná, y
elataque. Cada uno de estos atributos varía según la instancia. Pero… ¿cómo saber cuántos
enemigos se han creado en total?
Puedes crear una variable de clase que cuente la cantidad. Algo como:
Enemigo.java
Enemigo.numeroDeEnemigos
Análogamente podemos crear métodos de clase. Este tipo de métodos se pueden invocar
directamente desde la clase sin tener que crear una instancia. Sin embargo pueden ser
invocados por objetos, solo que no es recomendable porque no aclara su naturaleza.
Los métodos estáticos son útiles para obtener el valor de las variables de clase. Para obtener
la variable numeroDeEnemigos podrías usar el siguiente método.
Enemigo.obtenerNumEnemigos();
Otro propósito lo podemos ver en los métodos de clase para utilidades. Por ejemplo, el
método de clase asList() de la clase Arrays, permite convertir un array en una lista, sin
tener que crear una instancia.
Declaración de constantes en Java— Las constantes son elementos que no pueden cambiar
su valor a lo largo de programa. Para declararlas usa la combinación de los
modificadoresfinal y static.
Esta constante podrá usarse en todo el proyecto. Por convención de nombres se espera que
escribamos nombres en mayúsculas y separando las palabras con guiones bajos.
Una de las formas de aplicar esta teoría es usar métodos set y get.
Normalmente cuando inicias creando tus primeras clases, accedes a los atributos de las
instancias de la siguiente forma:
miObjeto.atributo1 = 2;
miObjeto.atributo2 = "Cadena";
El papel que juegan los métodos set y get es restringir el acceso directo de tus atributos con
el modificador private y en su lugar construir método public que obtengan y asignen su
valor.
El código anterior muestra la existencia de tres atributos privados. Por cada uno existe un
método que comienza con las palabras en inglés “get” y “set”, donde get*() obtiene el
valor del atributo con la sentencia return y set*() asigna un nuevo valor a través de un
parámetro.
Así evitas el contacto directo y solo debes llamar a los métodos.
miObjeto.setAtributo1(2);
String atributo2 = miObjeto.getAtributo2();
Luego seleccionas los atributos a los cuales deseas generar los métodos get y set.
11. EL OPERADOR NEW PARA CREAR OBJETOS EN
JAVA
Una vez tienes tu clase definida, ya es posible instanciar objetos que comiencen a contribuir
a la aplicación. La creación de un nuevo objeto se lleva a cabo del operador new.
Para crear un nuevo objeto de la clase Cliente sería:
El siguiente es un constructor que permite asignar valores a todos los campos del cliente.
La herencia es el proceso de transmitir atributos y métodos de una clase a otra. Donde la clase
que se toma como base se le denomina superclase y la que hereda se le llama subclase.
Usa la palabra reservada extends para declarar que una clase hereda de otra.
Veamos un ejemplo entre una clase llamada Estudiante, la cual hereda de Persona.
Persona.java
Estudiante.java
public Estudiante(String nombre, String telefono, float nota1, float nota2, float nota3) {
super(nombre, telefono);
this.nota1 = nota1;
this.nota2 = nota2;
this.nota3 = nota3;
}
La referencia super representa a la superclase Persona, este facilita pasar los parámetros
necesarios, para la satisfacción de su constructor.
También invocamos el método obtenerInformacion() alojado en la clase padre, para
sobrescribir el de la clase Estudiante.
Si creáramos una instancia de ambas clases veremos como el
método obtenerInformacion()tiene dos comportamientos diferentes.
Main.java
Nombre: Carlos
Teléfono: 3445569
Nombre: Arliz
Teléfono: 34456678
Notas: 3.4, 4.5, 1.0
Una clase abstracta es aquella de la cual no se pueden crear instancias directamente. Sin
embargo, se pueden crear subclases a partir de ellas. Definir una clase de este tipo requiere
usar la sentencia abstract en la declaración.
Este concepto permite organizar las clases semejantes. También obliga a los programadores
a sobrescribir métodos importantes que garanticen el correcto funcionamiento de un patrón.
Dentro de una clase abstracta puede que existan 0 o más métodos abstractos. Un método
abstracto es aquel que se declara pero no se implementa, con el fin de que las subclases si lo
hagan.
Por ejemplo…
Tenemos la clase Objeto3D para representar aquellos componentes que tienen vértices,
índices y una textura definida. Con esta clase podemos definir subclases
como Cubo,Esfera y Piramide. Aunque las tres son objetos tridimensionales, requieren un
renderizado distinto según su geometría. Por lo que el método para renderizar debe ser
abstracto y por ende la clase Objeto3D.
void crearGeometria() {
//...
}
void texturizar() {
// ...
}
// Método abstracto
abstract void renderizar();
Las interfaces son un mecanismo para crear un tipo sin definir su implementación. Son
similares a las clases, solo que estás contienen constantes, firmas de métodos sin
implementar, métodos estáticos, métodos por defecto y tipos anidados.
Las clases normales pueden heredar los métodos de las interfaces. Sin embargo no se
considera Herencia si no Implementación.
Para crear una interfaz usa la palabra reservada interface. Al implementarla sobre una clase
usa implements.
public interface NombreInterfaz{
// Constantes...
// Firmas de métodos...
// Tipos...
}
También es importante recalcar que una clase puede implementar varias interfaces. A lo que
se le llama herencia múltiple.
Conceptualmente una interfaz es un medio para comunicar dos elementos.
Por ejemplo…
Un médico puede comprender la información de la presión arterial de un paciente a través de
un estetoscopio. En este caso, el estetoscopio sería una interfaz.
Otro ejemplo sería relacionar un Leon con estados como ser Mamifero y Carnivoro. Ambas
condiciones son una interfaz que permite comunicar la supervivencia del león con recursos
y situaciones naturales, como es comer carne o alimentarse de leche.
@Override
public void desgarrar() {
// Acciones y condiciones para desgarrar
}
}
Cuando esto sucede, se crea un objeto del tipo Exception que contiene los datos del error.
Luego es pasado al sistema para informar del inconveniente.
Las expceciones se basan en la clase Throwable, la cual tiene implementado el
comportamiento para interrumpir el flujo en caso de que se presenten condiciones
específicas.
Cuando ocurren problemas graves en el proceso de la máquina virtual de Java esta lanza
objetos de tipo Error.
Por otro lado, si el problema no es tan grave para el sistema, se lanzan objetos del
tipoException o alguno de sus herederos
(RuntimeException, NullPointerException,IllegalAccessException, etc).
Por ejemplo…
Si tuvieses un método que solo asigna números positivos a un atributo sería conveniente
comprobar antes que el parámetro satisfaga la condición. Algo como:
PruebaExcepciones.java
int valor;
}
}
El bucle escrito en el main cuenta desde 1 a 8, donde se asigna el valor del índice al atributo
de un objeto PruebaExcepciones nuevo. Como truco, al llegar a 7 multiplicamos por -
1 para producir un número negativo.
El método asignarValor() es marcado para lanzar excepciones con la
sentencia throwsjunto al tipo de excepción. Luego hacemos efectivo el lanzamiento si el
parámetro número es negativo.
Para manejar la excepción se usa un bloque try-catch, donde try recibe las instrucciones a
procesar y catch realiza las acciones en caso de que haya atrapado la excepción. En nuestro
caso imprimimos la pila de seguimiento sobre la excepción con printStackTrace(), la cual
indica las capas sucesivas donde ocurrió el inconveniente.
El resultado al ejecutar sería:
Las colecciones son objetos que agrupan elementos asociados en una misma estructura.
Hablo de listas, mapas, conjuntos, colas, etc.
La librería de las colecciones trae consigo componentes que generan el comportamiento de
las unidades que agruparán elementos. Veamos la definición de algunos:
Los componentes anteriores producen gran cantidad de clases que nos permiten agrupar
datos, como por ejemplo:
▪ ArrayList: Lista basada en un array de tamaño variable, creada con base en la interfaz List.
▪ HashMap: Tabla hash basada en la implementación de Map. Cumple con todas las características de
Map y además permite añadir elementos con claves y valores nulos.
Veamos un ejemplo de ArrayList…
PruebaArrayList.java
import java.util.ArrayList;
import java.util.List;
Los Generics son tipos que permiten crear implementaciones de clases, métodos e interfaces
basados en parámetros.
En el ejemplo anterior del ArrayList vimos cómo esta clase permite crear una lista de un
tipo específico contenido en cuñas "<>". Dicho tipo se le denomina parámetro y evita que
se realice casting de los elementos al momento de acceder a estos.
Por ejemplo… si tuviésemos una clase llamada Barco la cual permite calcular características
como el peso total o la velocidad máxima, sería de utilidad poder tener precisión según las
propiedades del material empleado para su construcción.
En ese caso podríamos usar una clase genérica para satisfacer el enunciado “crear nuevo
barco a base de…”. Esto haría necesario la existencia de clases para los materiales
comoMetal, Madera, Aleacion, etc.
El lenguaje Java permite que los desarrolladores declaren clases dentro de otras clases. Ellas
reciben el nombre de clases anidadas, donde la clase que contenedora se le denomina clase
externa.
class ClaseExterna {
class ClaseAnidada {
}
}
Una clase anidada puede ser declarada como estática o no estática y se comporta como un
miembro más de la clase externa. La primera es llamada clase anidada estática y la
segundaclase interna.
Las clases internas pueden acceder a otros miembros de la clase externa, incluso si estos son
privados. En cambio una clase anidada estática no tiene esta oportunidad.
El ejemplo anterior muestra una clase externa llamada ScriptBaseDeDatos la cual contiene
una clase anidada estática llamada ColumnasTablaPerro. Esta representa las columnas de
una tabla perteneciente a una base de datos y contiene como miembros una serie de
constantes.
Si quisiéramos acceder algún campo desde algún lugar del proyecto lo haríamos de la
siguiente forma:
String id = ScriptBaseDeDatos.ColumnasTablaPerro.ID;
Uso de clases anónimas— Una clase anónima es un tipo de clase interna que se declara y se
instancia al mismo tiempo. Esta puede ser declarada dentro de bloque de códigos como el de
un método.
Su gran poder está en que en vez de ser tratadas como una declaración, se consideran una
expresión. Esto significa que puedes asignarlas a otra expresión existente dentro de un bloque
de código.
boton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Acciones...
}
}
);
Como ves, existe un botón al cual se le asigna una nueva interfaz de escucha con el
métodosetOnClickListener(). Este método recibe una instancia del
tipo OnClickListener.
Justo en ese parámetro podemos crear una clase anónima que satisfaga este requerimiento
con el operador new.
Si te fijas, estamos definiendo el cuerpo de una nueva clase sin nombre (por algo le llaman
anónimas), donde sobrescribimos el método onClick().
El compilador no arrojará errores, porque sabe que el cuerpo de esta nueva clase
implementada en la línea dará como resultado una instancia OnClickListener.
Los programas Java soportan la ejecución de múltiples hilos de trabajo. La clase que
permite crear este tipo de unidad de procesamiento es Thread.
Para crear un nuevo hilo se debe hacer uso de la interfaz Runnable, donde el código que se
ejecutará en el hilo se implementa en el controlador run().
Por ejemplo…
PruebaHilos.java
Una vez has creado un nuevo objeto Thread indicando el componente Runnable, entonces
inicias su ejecución con el método start().
Sincronizar hilos en Java con synchronized— La sincronización es un mecanismo para
evitar que dos o más hilos generen fallos de ejecución o difuminen la lógica de la aplicación,
al acceder a un mismo recurso.
Para evitar este tipo de inconvenientes usaremos la palabra reservada synchronized. Esta
sentencia bloquea el control para que solo un hilo tenga acceso al recurso. Así que hasta que
un hilo no acabe la operación, el siguiente deberá esperar. Además permite que los hilos
otorguen visibilidad a los datos procesados.
class EjemploSincronizacion {
private int i = 0;
El método metodoSincronizado() evita que un hilo adicional lo invoque hasta que el actual
lo termine de procesar. Además hace visible el estado actual a todos los hilos.
Dentro de variacionDelMetodoSincronizado() se sincroniza una sentencia. En este
casosynchronized recibe el objeto en el que serán protegidas las sentencias. Ambas
definiciones funcionan igual.
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
import android.annotation.TargetApi;
...
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ActividadPrincipal extends ActionBarActivity {
// ...
}
Java trae consigo anotaciones predeterminadas que podemos usar para varios propósitos.
Veamos algunas:
▪ @Deprecated: Anotación que marca una pieza de código como obsoleta, lo que significa que ya no
es recomendable usarla de nuevo. Esta anotación permite que el compilador muestre una alerta que
le indique al desarrollador que probablemente hay una nueva versión del código o una mejor manera
de realizar la tarea.
Esto produciría el siguiente efecto en Android Studio al utilizar el método.
▪ @Override: Indica al compilador que el método marcado será sobrescrito con base a la superclase.
Es de gran utilidad para diferenciar los métodos y prevenir errores.
La ilustración muestra como al añadir la anotación con el atributo “deprecation” el método que antes
se marcaba como obsoleto, ahora luce normal.
Aprendiendo Sobre La
Arquitectura De Android
James Revelo agosto 7, 2014 Fundamentos 0 Comments
Android está construido con una arquitectura de 4 capas o niveles relacionados entre sí. A
continuación veremos un diagrama ilustrativo extraído del libro Learning Android escrito
porMarko Gargenta y Masumi Nakamura:
El diagrama indica que la estructura de Android se encuentra construida sobre el Kernel de
Linux. Luego hay una capa de Librerías relacionadas con una estructura administradora
enTiempo de ejecución. En el siguiente nivel encontramos un Framework de apoyo para
construcción de aplicaciones y posteriormente vemos a la capa de Aplicaciones.
KERNEL DE LINUX
Aunque el proceso añade unos cuantos pasos más, no debes preocuparte por ello, ya que esta
tarea se le delega a la herramienta Gradle.
Google ha anunciado que Dalvik VM será reemplazada por una nueva máquina virtual
llamadaART (Android Runtime) en su nueva versión Android L. Por el momento no nos
preocuparemos por esta situación, pero es un dato muy importante a tener en cuenta.
CAPA DE APLICACIONES
▪ Una de las mayores ventajas es que le entrega el poder del flujo de construcción al
programador. Esto quiero decir que decidimos el orden de ejecución de tareas. Asimismo
podríamos elegir que archivos compilar primero, cuando detener la compilación, establecer
condiciones para que se recompile o no el código y muchas situaciones más.
▪ Ejecuciones incrementales: El poder de esta característica le ahorra al programador gran
cantidad de tiempo de espera. Al haber construcciones incrementales podemos decidir hasta
que punto queremos que se compile nuestra aplicación, es decir, si no es necesario compilar
una parte del código debido a la ausencia de errores, entonces se procede a compilar la
sección que aun no ha sido probada.
▪ Múltiples versiones: Gradle permite que construyamos varias versiones de nuestra
aplicación. Por ejemplo, si deseas construir tu aplicación para Jelly Beans y
para Kitkatentonces solo debes especificar que el proyecto tendrá dos variantes de
empaquetado, configurando la versión del SKD usada para cada versión.
▪ La ejecución y las pruebas se pueden realizar en un mismo proyecto.
▪ Ejecución en paralelo de tareas: Puedes ejecutar tareas en hilos diferentes para optimizar
el proceso de construcción.
Esas son las características más importantes, sin embargo, hay muchas más. Si lo deseas, te
invito a visitar el Sitio Oficial de Gradle para que te enteres de los avances de la
herramienta, revisar la documentación y descargar libros que te ayuden a comprender su
potencial.
Estructura De Un Proyecto En
Android Studio
James Revelo agosto 15, 2014 Android Studio 21 Comments
La carpeta app es la que contiene todo lo relacionado con tu proyecto, es la carpeta que nos
interesa por el momento y donde incluiremos los archivos necesarios para que nuestra
aplicación sea empaquetada. Si despliegas su contenido veras tres carpetas: build, libs y src.
Por ahora ignoraremos los demás archivos.
Normalmente la mayor parte del tiempo y fuerzas las usaremos en la carpeta src(Source).
Dentro de ella se ubica la carpeta main, la cual contiene todos los archivos fuente Java para
nuestra aplicación. La carpeta res (Resources) que contiene los recursos del proyecto (iconos,
sonido, diseños, etc.) y el archivo AndroidManifest.xml.
Es un archivo XML que contiene nodos descriptivos sobre las características de una
aplicación Android. Características como los building blocks existentes, la versión de
SDK usada, los permisos necesarios para ejecutar algunos servicios y muchas más. En pocas
palabras el Android Manifest es un panorama de toda nuestra aplicación.
Si abres el archivo en el editor verás un código similar a este:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</manifest>
Todas las aplicaciones deben contener este archivo por convención. El nombre debe
permanecer intacto, ya que se usa como referencia para el parsing de nuestra aplicación.
Elnodo raíz de este documento se representa con la etiqueta <manifest> y por obligación
debe contener un hijo de tipo <application>.
En el código anterior podemos observar que manifest posee dos atributos, xmlsn:android y
package. El primero no debemos cambiarlo nunca, ya que es el namespace del archivo.
El atributo package indica el nombre del paquete Java que soporta a nuestra aplicación. El
nombre del paquete debe ser único y un diferenciador a largo plazo.
La etiqueta <application> representa como estará construida nuestra aplicación. Dentro de
ella definiremos nodos referentes a las actividades que contiene, las librerías incluidas,
losIntents, Providers, y demás componentes.
Algunos atributos de la etiqueta <application> son:
▪ allowBackup: Este atributo puede tomar los valores de true o false. Indica si la aplicación
será persistente al cerrar nuestro AVD.
▪ icon: Indica donde está ubicado el icono que se usará en la aplicación. Debemos indicar la
ruta y el nombre del archivo que representa el icono. En este caso apuntamos a las carpetas
drawable donde se encuentra ic_launcher.png. Icono por defecto que nos
proporciona Android Studio.
▪ label: Es el nombre de la aplicación que verá el usuario en su teléfono. Normalmente apunta
a la cadena “app_name” que se encuentra en el recurso strings.xml (Más adelante lo
veremos).
▪ theme: Este atributo apunta al archivo de recursos styles.xml, donde se define la
personalización del estilo visual de nuestra aplicación.
Dentro de <application> encontraremos expresada la actividad principal que definimos al
crear el proyecto Test. Usaremos <activity> para representar un nodo tipo actividad.
<activity> tiene dos atributos: name, el cual se refiere a la clase Java que hace referencia a
esta actividad (Comienza con un punto “.”). Y el atributo label que hace referencia al texto
que se mostrará en la cabecera de la actividad. En este caso es el mismo string “app_name”.
Por el momento estudiaremos hasta este punto. En próximos artículos veremos el proposito
de los nodos <intent-filter>, <action> y <category>.
Uno de los recursos más relevantes es el archivo strings.xml que se encuentra dentro de la
subcarpeta values. Este fichero almacena todas las cadenas que se muestran en
loswidgets (controles, formas, botones, vistas, etc.) de nuestras actividades.
Por ejemplo, si tuvieses un botón cuyo título es “Presiona aquí”, es recomendable incluir
</resources>
El archivo strings.xml es muy útil para los desarrolladores. Una de sus grandes utilidades es
facilitar el uso de múltiples idiomas en tu aplicación. Esto se debe a que puedes externalizar
las cadenas del código java y seleccionar la versión del archivo strings.xml con el lenguaje
necesitado.
Personalmente te recomiendo que uses este archivo siempre, incluye todo tu texto y no dejes
nada por fuera, tu aplicación te lo agradecerá en el futuro.
En la carpeta layout encontrarás los archivos de diseño de todas tus actividades. En mi caso
existe el archivo activiy_my.xml. Este archivo representa el diseño de la interfaz de mi
actividad principal. En el se establecerán todos los widgets que vaya a agregar a la actividad.
Construir la interfaz a través de nodos XML es mucho más sencillo que la creación a través
de código Java. Adicionalmente Android Studio nos ha dotado de un panel de diseño
estilo Drag and Drop, lo cual es una bendición para los desarrolladores, ya que facilita
demasiado la creación de una interfaz de usuario.
Este archivo de diseño comienza con un nodo raíz llamado <RelativeLayout>. Un Layout es
el contenedor principal que define el orden y secuencia en que se organizarán los widgets en
nuestra actividad. Existen varios tipos de Layouts, como por ejemplo el LinearLayout,
GridLayout, FrameLayout, etc.
Android Studio crea por defecto un RelativeLayout porque permite crear un grupo de
componentes con ubicaciones relativas. Quiere decir que se ubicaran por referencias y no por
valores absolutos. Esto permite ajustar nuestras aplicaciones a cualquier tipo de pantalla para
dispositivos móviles.
Si abres el archivo de diseño de tu actividad verás algo como esto:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity">
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Si has sido atento también podemos encontrar el icono de la aplicación en una serie de
carpetas que comienzan por el cualificador drawable. Estas carpetas se relacionan
directamente con el tipo de densidad de pantalla donde se ejecutará nuestra aplicación.
▪ Mediun Dots per Inch(mdpi): Este tipo de pantallas tienen una densidad de 160 puntos por
pulgada.
▪ High Dots per Inch(hdpi): En esta clasificación encontraremos teléfonos cuya resolución
es de 240 puntos por pulgada.
▪ Extra high dots per inch(xhdpi): Resoluciones mayores a 340 puntos por pulgada
▪ Extra Extra high dots per inch(xxhdpi): Rangos de resoluciones mayores a 480 puntos por
pulgada.
Miremos una pequeña imagen ilustrativa:
El archivo R.java es una archivo que se autogenera dentro de la carpeta build, para linkear
todos los recursos que tenemos en nuestro proyecto al código Java.
Si abres el archivo podremos ver un código similar a este:
package com.TUPAQUETE.test;
Como ves, la clase R contiene clases anidadas que representan todos los recursos de nuestro
proyecto. Cada atributo tiene un dirección de memoria asociada referenciada a un recurso en
específico. Por ejemplo, la clase string posee el atributo hello_world, el cual representa
nuestro TextView en la actividad principal. Este recurso está ubicado en la
posición0x7f050002.
Justamente era lo que iba a decir. Finalmente llegamos a la carpeta “java”. Aquí se alojarán
todos los archivos relacionados con nuestras actividades y otros archivos fuente auxiliares.
Al abrir nuestro archivo MyActivity.java veremos toda la lógica necesaria para que la
actividad interactúe de manera correcta con el usuario.
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
@Override
public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu;this adds items to the actionbar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
// Handle action bar item clicks here. The actionbar will
// automatically handle clicks on the Home/Upbutton, so long
// as you specify a parent activity inAndroidManifest.xml.
int id = item.getItemId();
if(id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
}
Para toda actividad creada debemos extender una subclase de la superclase Activity. Más
adelante veremos que una actividad tiene un ciclo de vida y lo único que esta bajo nuestro
control es la manipulación de cada estado.
Si ya notaste, las actividades no tiene un punto de entrada main(). Esto se debe a que las
aplicaciones Android parten de múltiples puntos de ejecución. Pero esa característica será
objeto de estudio del próximo artículo.
Tutorial Básico Del Lenguaje
Xml
James Revelo agosto 22, 2014 Fundamentos 0 Comments
Este artículo tiene como fin abarcar las características principales sobre el lenguaje
XML.Con el fin de comprender el contenido de los archivos de recurso de un proyecto de
desarrollo en Android.
Veremos que es el lenguaje XML, por qué surge como herramienta de interoperabilidad,
cuáles son sus usos y cuál es la sintaxis para crear un documento XML.
¿QUÉ ES XML?
XML propone una sintaxis cómoda para las maquinas y los humanos, siendo un lenguaje
afable para la construcción de estructuras complejas.
OK, comencemos a estudiar las partes que conforman un documento XML y que sintaxis
debemos usar.
PRÓLOGO
El prólogo es una declaración XML no obligatoria que especifica algunas características del
documento, como por ejemplo la versión de XML que se usa o el tipo de encriptado. El
estilo de declaración sería como la siguiente línea:
Esta expresión usa como inicio la palabra reservada “xml” y un signo de interrogación de
apertura ‘?’. El atributo version hace referencia al estándar XML usado
y enconding indica el estándar de encriptado. Recuerda que el encriptado es la forma de
traducir los caracteres que hay en el documento en forma binaria.
Existen varias formas de encriptado, pero normalmente el estándar usado es UNICODE. Los
formatos más populares son el UTF-8 y UTF-16. El primer formato representa cada carácter
con 8 bytes y el segundo con 16 bytes.
COMENTARIOS
Para usar comentarios abrimos con la expresión “<!–” y cerramos con los caracteres “–>” .
Todo el texto que este comprendido entre estos símbolos será ignorado por el Parser. Veamos
un ejemplo:
Los comentarios son mensajes destinados al entendimiento del código por parte del
programador. Solo tiene fin informativo, así que serán pasados por alto a la hora del análisis
XML.
ELEMENTOS
También llamados Building Blocks. Son la base de un documento XML, ya que al fin y al
cabo ellos representan nuestra información. Al igual que en HTML, un elemento será
descrito por una etiqueta inicial envuelta en paréntesis angulares <elemento> y una etiqueta
de cierre con una barra inclinada antecedida al nombre del elemento </elemento>.
Y al texto que se encuentra en el interior del elemento se le llama contenido.
Por ejemplo, declaremos un elemento llamado tabla:
<tabla>[contenido]</tabla>
En casos donde el elemento no describe algún contenido podemos abreviar la etiqueta de la
siguiente forma:
<tabla/>
Con esta disposición reducimos a una sola expresión la apertura y cierre de un bloque de
construcción XML.
▪ Puede comenzar con un guión bajo “_”, una letra mayúscula o una letra minúscula del código.
▪ Puedes usar guiones ‘-‘ dentro del nombre de un elemento. Además puedes incluir dígitos
dentro de tu nombre.
▪ Las etiquetas son sensibles a mayúsculas y minúsculas. Procura abrir y cerrar un elemento
con el mismo nombre.
▪ Nunca, por lo que más quieras uses espacios los nombres, esto producirá un error de
Parsing.
▪ La palabra xml no puede ser usada en el inicio del nombre del elemento, ya que está
reservada.
Algunos ejemplos de buenos nombres serian:
EL ELEMENTO RAÍZ
Luego de haber declarado el prologo sigue el elemento raíz (root element). Este componente
representa la cabeza de la jerarquía estructural del archivo XML. Solo debe existir
únicamente un elemento raíz que describa el contexto.
Veamos un ejemplo de un documento XML que guarda la información sobre facturas de
unestablecimiento comercial:
<fila id_factura="1001" fecha="20/12/2014 12:01:23 "/>
<fila id_factura="1002" fecha="21/12/2014 07:23:29 "/>
<fila id_factura="1003" fecha="22/12/2014 14:34:10 "/>
En este caso el Parser no procesará correctamente la información debido a que cada nodo
<fila> esta al mismo nivel, por lo tanto no hay jerarquía. Es por eso que decides añadir un
elemento raíz que encierre el contenido llamado <factura>:
<factura>
<fila id_factura="1001" fecha="20/12/2014 12:01:23 "/>
<fila id_factura="1002" fecha="21/12/2014 07:23:29 "/>
<fila id_factura="1003" fecha="22/12/2014 14:34:10 "/>
</factura>
Con este detalle el parser ya puede comprender que está sucediendo en el modelo del
documento.
ELEMENTOS HIJOS
Luego de declarar tu raíz siguen los elementos que están por debajo. En el caso anterior,
<fila> era un elemento hijo de <factura>. Y los tres elemento fila estaban al mismo nivel, por
lo tanto eran hermanos. Es posible anidar un elemento dentro de otro, recuerda que estamos
siguiendo una jerarquía, así que cada elemento interior estará bajo la dependencia de su
padre.
▪ Los atributos deben contener un nombre y un valor de texto expresado a través del signo de
igualdad ‘=’.
▪ El valor debe estar contenido entre comillas simples o dobles. Ambas cumplen la misma
función, pero la elección depende de cada quien.
▪ Los nombres de los atributos cumplen exactamente las mismas reglas de la construcción de
nombres para elementos.
▪ Si un atributo no tiene valor establecido debes poner un vació entre comillas (” ” ó ‘ ‘).
▪ No deben haber nombres de atributos repetidos dentro de un elemento. Cada nombre ha de
ser único.
▪ Si deseas que el valor del atributo tenga comillas simples o dobles, establece
comolimitador a par de comillas que no serán usadas. Es decir, si deseas que tu atributo
tenga el valor “1234”, entonces debes delimitarlo con las comillas simples: ‘ “1234” ‘.
CONTENIDO DE ELEMENTOS
El contenido de los elementos permite describir el texto al cual se le dará formato. El
contenido lo expresas entre las etiquetas de apertura y cierra como vemos a continuación:
Carácter Representación
& &
< <
> >
“ "
‘ '
De modo que si deseas emplear alguno de estos símbolos, debes reemplazarlo por la
expresión que lo representa.
Supongamos que deseamos representar las materias que está viendo el estudiante. Por ello
incluimos un nuevo atributo llamado materias:
Si se necesitara procesar cada materia individualmente, ¿crees que sería útil la estructura
actual del formato XML?
¡Claro que no!…ya que el valor de materias es solo una cadena, lo que implicaría un proceso
adicional de procesamiento de cadenas en nuestro contexto. Pero si usáramos elementos en
vez de ese atributo tendríamos lo siguiente:
Con esta jerarquía podemos identificar de manera secuencial cada elemento materia para
conseguir procesar la información en orden.
CDATA (character data) es una sección especial en un archivo XML, que le indica al
Parser que no interprete como lenguaje marcado todo lo que se encuentre adentro. Para los
que han usado Blogger de Google, sabrán que la plantilla XML de la cual se crea el
documento HTML del blog usa esta sección.
Es común usar esta sección para incluir código CSS o Javascript, para que el Parser no lo
interprete como marcado, debido a que usan frecuentemente los caracteres de escape
restrigindos (‘&’, ‘<‘, ‘>’,… ).
La sección CDATA se inicia y termina de la siguiente forma:
<![CDATA[
[Contenido no interpretable como marcado]
]]>
Después de que el Parser haya analizado el documento XML, todo el texto en las
seccionesCDATA habrá quedado intacto.
Son una forma de agrupar atributos o elementos bajo un mismo encabezado para
diferenciarlos de otros. Esto permite contextualizar los bloques de tal forma que sean
distinguidos en situaciones diferentes.
Puedes asemejarlo con los namespaces de C++ o los paquetes de Java. Dentro de estos
espacios son referenciados objetos de información que solo conciernen a este nombre de
espacio. Lo cual permite diferenciar el uso de la información.
Veamos el siguiente ejemplo:
<biblioteca>
<libro >
<titulo>Fundamentos de programación</titulo>
<paginas>213</paginas>
<capitulo>
<titulo>Introducción</titulo>
</capitulo>
</libro>
</biblioteca>
Este documento describe los libros que se encuentran en una biblioteca. Como ves, la
etiqueta <biblioteca> es el nodo principal, en su interior está la etiqueta <libro> y dentro de
él empezamos a definir componentes que hacen parte de la estructura de un libro como
el titulo, las páginas y los capítulos.
¿Qué notas?… ¡exacto!, el libro tiene una etiqueta <titulo> para referirse al nombre del libro,
y a su vez cada capítulo tiene una etiqueta <titulo> para referirse al nombre del capítulo.
Cualquier persona puede entender esta ambigüedad debido a que es una representación visual
y estructural, pero…. ¿podemos decir lo mismo de Parser?
Esta situación haría que el parser se confundiera y provocará malos resultados cuando
busquemos información. El parser se preguntaría:
El elemento <libro> es padre de <capitulo>, pero ambos tienen como hijo a <titulo>, ¿qué
sucede?
Bueno, antes de definirlos debemos conocer primero que son URLs, URIs y URNs.
Uniform Resource Locator (URL): Es un formato que permite obtener recursos de alguna
ubicación.
Popularmente conocemos este concepto debido a que frecuentemente buscamos páginas web
en internet con ellas. A continuación vemos su estructura:
[Esquema]://[Dominio]:[Puerto]/[Ruta]?[Query]#[Id]
http://www.hermosaprogramacion.com
Aunque no usa todo el formato, podemos identificar que el esquema usado es HTTP y el
dominio seria “hermosaprogramacion”.
▪ Uniform Resource Identifier(URI): Es solo una cadena única que representa algo y puede
tener el formato de las URLs y URNs.
▪ Uniform Resource Name(URN): Es un nombre que identifica algún objeto para
diferenciarlo de los demás. Normalmente tienen el siguiente formato:
Urn:ISBN:9098231847381
Las URLs y URNs pueden ser URIs. Una URL muestra la ruta única de un recurso y una
URN un nombre único. Ambas pueden representar una URI que posibilite la creación de
namespaces en nuestros archivos XML.
Para crear un namespace primero debemos elegir una URI que nos permite diferenciar su
contexto. Por lo general se usa un formato URL ya que el dominio de cada compañía es
único, lo que asegura una identificación que no se repetirá. Cabe destacar que aunque la URI
tenga un formato URL no significa que la URI sea una URL.
Para mi caso en particular usaré la siguiente URI:
"http://www.hermosaprogramacion.com/namespaces/ejemplos/noEjemplo"
xmlns="URI"
<forex fecha-actual="19/08/2014"
xmlns=" http://www.hermosaprogramacion.com/namespaces/ejemplos/no1">
<par nombre="EURUSD" current="1.323"/>
<par nombre="EURGPB" current="1.845"/>
<par nombre="AUDUSD" current="0.8976"/>
</forex>
Como ves, hemos declarado la URI en el nodo raíz. Esto significa que todos los componentes
dentro del elemento también harán parte del namespace identificado con la URI establecida.
Este estilo de declaración se le llama namespace implícito o por defecto.
La otra forma se le llama declaración explícita. Haremos exactamente lo mismo que en la
forma implícita solo que esta vez seleccionamos que elementos específicos queremos que
hagan parte del namespace, a través un sistema de etiquetado:
<FX:forex fecha-actual="19/08/2014"
xmlns:FX=" http://www.hermosaprogramacion.com/namespaces/ejemplos/no1">
<par nombre="EURUSD" current="1.323"/>
<par nombre="EURGPB" current="1.845"/>
<par nombre="AUDUSD" current="0.8976"/>
</FX:forex>
Apliquemos este concepto de namespaces al ejemplo de la biblioteca que puede llegar a tener
problemas.
<b:biblioteca
xmlns:b="http://www.hermosaprogramacion.com/namespaces/ejemplos/no2">
<b:libro >
<b:titulo>Fundamentos de programación</b:titulo>
<b:paginas>213</b:paginas>
<capitulo xmls="http://www.hermosaprogramacion.com/namespaces/ejemplos/no2-capitulo">
<titulo>Introducción</titulo>
</capitulo>
</b:libro>
</b:biblioteca>
{http://www.hermosaprogramacion.com/namespaces/ejemplos/no2}titulo
{http://www.hermosaprogramacion.com/namespaces/ejemplos/no2-capitulo}titulo
"android:text="@string/name""
Esa sentencia nos indica que el atributo texto de las vistas se encontrará almacenado en el
archivo strings.xml que tenga el nombre name.
Como notas, XPath funciona con un estilo de navegación a través de barras laterales y
expresiones regulares para encontrar el elemento que necesitamos.
¿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
unnuevo 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.
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
anim/ Contiene archivos XML que representan animaciones especiales para views.
Aquí encontrarás archivos XML con definiciones de listas de estados de color
(Color State List). Estas listas determinan el color de un
color/ componente dependiendo del estado en que se encuentre.
Archivos XML que establecen las características para los menús usados en la
interfaz. Normalmente contienen definiciones sobre los ítems albergados en un
menu/ menú y las agrupaciones entre ellos.
Almacena aquí todos aquellos archivos que deseas leer directamente como un
raw/ flujo de caracteres estándar (InputStream).
Archivos XML que contienen datos simples como enteros, strings, booleanos,
colores. Puedes agrupar estos elementos en las siguientes convenciones de
archivos:
▪ strings.xml para cadenas
▪ colors.xml para definiciones de colores en hexadecimal.
▪ dimens.xml para dimensiones de márgenes, padding, tamaños, etc.
▪ styles.xml para los estilos de interfaz que tendrá la aplicación.
values/ ▪ arrays.xml para arreglos de elementos.
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>
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
ldrtl(lectura de derecha a
izquierda),ldrtl(lectura de izquierda a
Dirección del layout ldrtl, ldrtl derecha)
Ancho mínimo de la
pantalla sw<N>dp sw480dp, sw240dp
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.
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.
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.
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,
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 recurso R.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;
}
Primero se obtiene el image view a través del método findViewById() y luego se le asigna
el identificador del drawable R.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.
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" />
@[<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
ejemplo string.
▪ <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 tipo dimen.
<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>
<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>
</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
identificadorandroid.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
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>
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.xmla 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"/>
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"/>
▪ 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>
Uso De Strings En Android
Como Recursos De Texto
James Revelo agosto 24, 2015 Fundamentos 17 Comments
En este artículo veremos el uso de strings en Android para el manejo de recursos de texto en
nuestras aplicaciones. Esto implica conocer muy bien el archivo strings.xml y las etiquetas
XML que podemos usar dentro de él.
Nos apoyaremos en la potencia de Android Studio al momento de generar automáticamente
strings dentro de los recursos.
También veremos el formateo y la aplicación de estilos a las cadenas. Casos para el uso de
caracteres especiales como apostrofes, comillas dobles, signos mayor qué y menor qué, etc.
Incluso la aplicación de marcado HTML para representar mejor el contenido.
<resources>
<string name="app_name">Uso De Strings En Android</string>
LA ETIQUETA <STRING>
Representa un string simple que al momento de ser compilado produce un tipo String para
el código Java.
Para declarar este elemento dentro de strings.xml es necesario que exista un padre del
tipo<resources> o de lo contrario no se reconocerá. Esto se muestra en la siguiente sintaxis:
Para acceder al contenido de un string a través del código, se usa la clase R de la siguiente
forma:
R.string.nombre_string
@string/nombre_string
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
En la vista de diseño de Android Studio podemos percibir el valor del texto gracias al árbol
de componentes, el panel de propiedades y obviamente reflejado en la previsualización.
¿Cómo hacer para obtener el valor de un string en código?
Uno de los métodos es usar la clase Resources, la cual representa la carpeta res dentro del
código. Esta provee métodos get*() para conseguir varios tipos de valor almacenados en
recursos.
En este caso particular sería el método getString(). Solo pasas como parámetro el
indicador y así obtendrás su contenido.
Por ejemplo… obtengamos el valor del string app_name y asignémoslo al text view de la
actividad. Esto lo haremos dentro del controlador onCreate() de ActividadPrincipal.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
helloWorld.setText(getText(R.string.hello_world));
Otra forma de contener elementos de texto en los recursos es a través de arreglos. La etiqueta
que nos permitirá este funcionalidad es <string-array>.
El identificador de este componente se define con el atributo name y cada elemento del
arreglo se representa con elementos hijos del tipo <item>. El contenido de cada item sería
un string.
El acceso a un array de strings en java se realiza con la clase anidada estática R.array.
R.array.nombre_array
@array/nombre_array
Por ejemplo…
Uno de los usos comunes de un array de strings se da en el view Spinner. Recuerda que este
control despliega una lista opciones para selección del usuario.
Comprobémoslo cambiando el text view de la actividad por un spinner de la siguiente forma.
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<string-array name="posiciones">
<item>Top</item>
<item>Mid</item>
<item>Bot</item>
<item>Jungla</item>
</string-array>
Los plurales son strings que representan diferentes cantidades de un texto según la situación.
Por ejemplo…
Al realizar una búsqueda de elementos en tu aplicación tal vez quieras informarle al usuario
cuantos fueron encontrados. Puede que no se haya encontrado ninguno, o tal vez uno o quizás
varios.
“n elementos encontrados”
Donde se reemplazaría n por la cantidad. Por lo tanto al tener la expresión n=1, el resultado
sería:
“1 elementos encontrados”
Esta sería una solución para abarcar todas las opciones, pero produce resultados anómalos.
Necesitaríamos tres tipos de frases para poder mantener la integridad de nuestra gramática.
Las constantes que se ven para quantity definen cantidades estándar. Veamos una tabla con
las definiciones:
Valor Descripción
R.plurals.nombre_plural
Ejemplo de plurales— Vamos a crear un plural que se refiera a una cantidad hipotética de
productos encontrada en una búsqueda.
Para ello limpiamos el método onCreate() de la actividad y reemplazamos el spinner
anterior por un text view.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<plurals name="noProductosEncontrados">
<item quantity="one">Se encontró %d producto</item>
<item quantity="other">Se encontraron %d productos</item>
</plurals>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
if (cantidad == 0) {
textView.setText(R.string.zero);
} else {
Resources res = getResources();
String string = res.getQuantityString(
R.plurals.noProductosEncontrados,
cantidad,
cantidad);
textView.setText(string);
}
Para evitarlo, creamos un nuevo string simple con el valor correcto y luego usamos
un if para diferenciar entre ambos resultados producidos por la cantidad aleatoria producida
con la claseRandom.
Cuando creas un plural Google recomienda añadirle como mínimo los
casos "one" y "other"para el soporte de la mayoría de lenguajes. Además indica que el
caso "one" debe tener el placeholder %d para darle el tratamiento en otros lenguajes donde
“1” no se interpreta como en el español. Esto facilita la comprensión y trabajo a los
traductores.
Si ejecutas la aplicación tendrías resultados similares a la siguiente ilustración.
Existen casos donde deseamos poner caracteres especiales dentro de nuestros recursos strings
como lo son acentos, símbolos o caracteres que hacen parte de XML. Sin embargo hacerlo
de forma estática no produce resultados deseados.
¿Cuál es el resultado?
Las comillas no aparecerán.
Las comillas dobles y los apóstrofos no serán interpretados por el framework de Android a
no ser que antepongas una barra vertical (\' y \"). Esto se debe a que las secuencias de
caracteres en Java usan estos símbolos como escape para representar dichos elementos.
El ejemplo anterior quedaría de la siguiente forma.
<string name="frase">\"Su activo más valioso puede ser su voluntad de persistir más que cualquier otra
persona\"</string>
De forma similar podemos usar las otras secuencias de escape que existen para los strings en
Java.
Secuencia de escape Descripción
\b Inserta un retroceso
\f Comienzo de página
\' Comilla simple o apóstrofo
\\ Backslash
Por ejemplo, si quisiéramos introducir una nueva en un string usaríamos la secuencia \n.
<string name="interrogacion">"?"</string>
<string name="arroba">"@"</string>
Si estos símbolos son usados en otra posición no es necesario usar las comillas.
Caracteres de escape en XML— En el artículo Tutorial Básico Del Lengueje Xml vimos
que hay 5 caracteres que no pueden ser usados normalmente dentro de los contenidos de una
etiqueta, ya que hacen parte de la notación XML.
Carácter Representación
& &
< <
> >
“ "
‘ '
Ampersand :
<string name="ampersand_mal">Johnson & Johnson</string>
<string name="ampersand_correcto">Johnson & Johnson</string>
Menor qué:
<string name="menor_que_mal">3<2</string>
<string name="menor_que_correcto">3<2</string>
Mayor qué:
<string name="etiqueta"><string></string>
Comillas dobles:
<string name="comillas_dobles_mal">"Coldplay"</string>
<string name="comillas_dobles_correcto">\"Coldplay\"</string>
Sorprende un poco que el primer ejemplo no funcione. Esto se debe a que el parser cambia
primero a texto plano los caracteres de escape XML y luego convierte el contenido resultante
en un tipo String de java. Por eso es necesario usar los escapes de java también.
Apóstrofos:
<string name="apostrofos_mal">Signo de escritura (') que se emplea para indicar la elisión de una
vocal.</string>
<string name="apostrofos_correcto">Signo de escritura (\') que se emplea para indicar la elisión de una
vocal.</string>
Otro ejemplo podría ser el uso del carácter que representa una octava en música con el
código\u266A.
Los recursos de strings también pueden ser formateados a través de parámetros especificados
por placeholders. Si tienes experiencia con la clase String de java, sabrás que el método
estático String.format() nos permite añadir formato.
Para conectar este método con un recurso string simplemente debes añadir placeholders que
indiquen el tipo de parámetro a reemplazar dentro de la cadena más la posición que se desea
ocupar.
Veamos un ejemplo:
El anterior ejemplo tiene dos parámetros: %1$s y %2$s. El primero representa un string en
java (%s) y su posición es determinada en el parser con 1$. El segundo es de tipo entero (%d)
y está en segunda posición 2$.
Ve al método onCreate() de la actividad y obtén el recurso string que acabos de ver. Luego
usa el método format() asignando dos valores correspondientes y por último setea el
resultado en el text view.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
Como era de suponer, el contenido XML de un string puede ser estilizado usando marcado
Html. Podemos usar las siguientes etiquetas:
Por otro lado, para asignar el recurso programáticamente debemos usar el método
estáticoHtml.fromHtml() para traducir las etiquetas Html. De lo contrario, en tu string
saldrán las etiquetas textualmente.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
Si pruebas el código anterior verás que no se aplican los estilos. La solución está en usar
secuencias de escape, debido a que el parser al transformar el texto ha ignorado todo el html.
Sin embargo puedes ignorar completamente el contenido de una etiqueta <string> con la
cláusula CDATA. Con ello pasarías un código completo Html al método fromHtml() para que
este interprete la cantidad de etiquetas que pueda (no todas son aceptadas).
Probemos usando el código html que tiene la descripción del método fromtHtml() en la
documentación oficial.
<string name="string_html_cdata">
<![CDATA[
<div>
<h4>
<span>
public static
<a href="/reference/android/text/Spanned.html">Spanned</a>
</span>
<span>fromHtml</span>
<span>(<a href="/reference/java/lang/String.html">String</a> source)</span>
</h4>
<div>
<div> Added in <a href="/guide/topics/manifest/uses-sdk-element.html#ApiLevels">API level
1</a></div>
</div>
<div>
<div>
<p>Returns displayable styled text from the provided HTML string.
Any <img> tags in the HTML will display as a generic
replacement image which your program can then go through and
replace with real images.
</p>
<p>This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.</p>
</div>
</div>
</div>
]]>
</string>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
SpannableStringBuilder stringBuilder =
new SpannableStringBuilder(getString(R.string.hello_world));
En primera instancia creamos una instancia de SpannableStringBuilder con una copia del
string hello_world.
Luego a través del método setSpan() aplicamos el estilo con los siguientes parámetros.
public void setSpan(Object what, int start, int end, int flags)
Debido a que solo necesitamos colocar en negrilla la primer letra, entonces el índice inicial
del string es 0 y el final será 1.
La bandera Spanned.SPAN_EXCLUSIVE_EXCLUSIVE evita que el tamaño del string cambie o
tenga tamaño 0.
Si ejecutas la aplicación tendrás el siguiente resultado.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actividad_principal);
SpannableStringBuilder stringBuilder =
new SpannableStringBuilder(getString(R.string.hello_world));
stringBuilder.setSpan(new ForegroundColorSpan(Color.RED),
0, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Veamos cómo hacer una pequeña traducción del español al inglés e italiano.
<string name="action_settings">Configuración</string>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ActividadPrincipal">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="43dp"
android:layout_marginRight="43dp"
android:text="@string/boton_busqueda" />
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:entries="@array/estado_civil" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="@string/etiqueta_estado_civil"
android:textSize="50sp" />
</RelativeLayout>
3. A continuación crearemos las traducciones para cada uno de los strings que tenemos. Abre
el archivo strings.xml y selecciona la opción emergente Open Editor en la parte superior
del espacio de trabajo.
Otra forma de acceder al editor de traducciones es presionar click derecho sobre el
archivostrings.xml y seleccionar Open Translations Editor.
6. Ahora realiza el mismo procedimiento con la traducción italiana (Usé Google Translator,
quien sepa italiano podría colaborarme con mejores traducciones).
7. Abordemos la traducción del array de strings. Esto requiere la creación de strings
simples que se referencien dentro de cada ítem. De lo contrario, no tendremos la traducción
para estos elementos.
Crea tres nuevos recursos dentro de strings.xml. Luego asígnalos a las etiquetas <item> en
el orden establecido.
<string name="estado_soltero">Soltero</string>
<string name="estado_casado">Casado</string>
<string name="estado_viudo">Viudo</string>
<string-array name="estado_civil">
<item>@string/estado_soltero</item>
<item>@string/estado_casado</item>
<item>@string/estado_viudo</item>
</string-array>
values-it/strings.xml
Si revisas la jerarquía de la carpeta res verás que tienes el subdirectorio values por defecto
más otros dos, values-en y values-it.