Está en la página 1de 13

Lab1 - Conexión de la interfaz con código Java

En este primer ejercicio, queremos que los alumnos se sientan cómodos escribiendo
código en Android, tanto XML como clases y métodos. Para ello, haremos una aplicación
muy simple, y le aplicaremos una serie de mejoras. La aplicación consistirá de una única
actividad encargada de recoger dos números, A y B, para poder calcular su módulo y
devolverle el resultado al usuario.

A. Descripción
En este ejercicio, no habrá código inicial, sino que los alumnos deberán crear un nuevo
proyecto con SDK mínimo de nivel 3 (Android 1.5), y comenzar a construir la aplicación.
Como primer punto a tener en cuenta, y como buena práctica de programación, nos
gustaría separar todas las clases de nuestros proyectos en sub-paquetes, de esta forma,
las actividades estarán en un paquete “Activities”, los algoritmos en un paquete “logic”,
etcétera. El paquete base “com.sistemas.android…” se deja a elección del alumno.

Una vez creado el proyecto, deberíamos abrir el archivo main.xml situado en la carpeta
res/layouts, y veremos que tenemos un layout lineal (LinearLayout), donde los elementos
se van colocando uno debajo del otro. El primer elemento que vemos es un TextView que
tiene como texto un elemento string, éste lo podremos encontrar en la carpeta
res/values/strings.xml, y Eclipse nos abrirá el editor. Como vemos, el string “hello” tiene
un determinado valor. Lo que haremos es cambiarlo, y crearemos dos strings, “tituloA” y
“tituloB”, los cuales utilizaremos para decirle al usuario dónde debe introducir los
números A y B respectivamente. Podemos ponerles de valor “A:” y “B:”.

B. Implementación.
B.1.- Entrando en código XML
Ahora volvamos al archivo main.xml. Éste es el archivo que define lo que se ve en nuestra
actividad, que aunque no hemos visto, sabemos que carga este elemento. Gracias a los
XML, podemos hacer grandes cambios en la interfaz sin tener que cambiar una sola línea
de código. Veámoslo. Bajo el TextView que vemos, vamos a añadir una pareja de TextView
y EditText por cada argumento que necesitamos para calcular el módulo, es decir, una
pareja para el argumento A y otra para el argumento B. No tenemos que preocuparnos de
mucho, sólo de escribir el siguiente código bajo el primer TextView:
Como vemos, cada elemento tiene tres atributos, el id, su ancho y su alto. Todos los
elementos (o Views) deben tener definido su ancho y su alto, y los dos valores más
conocidos son "fill_parent" (ocupa todo el espacio posible) y “wrap_content" (ocupa
sólo el espacio necesario para mostrar tu contenido). De esta forma, lo que les estamos
diciendo es que ambos deben coger todo el ancho que puedan, pero sólo aquella altura
que necesiten. ¿Qué pasa si cambiamos la altura de “wrap_content" a “fill_parent"”?
Pruébenlo, lo entenderán enseguida. Ahora, el id. ¿Para qué sirve? El id identifica
unívocamente a cada vista dentro del archivo (podemos tener otros esquemas XML y
utilizar los mismos ids), y es lo que nos permite tener acceso a estas vistas desde el código
Java, pero eso lo veremos más adelante. Bajo estas dos vistas, necesitamos realizar
exactamente lo mismo pero para el argumento B, luego lo único que hay que hacer es
copiar el código y ponerlo justo debajo, cambiando los ids de “tvA” a “tvB” y de “etA” a
“etB” respectivamente. Si no lo hacemos, no podremos modificar estas vistas desde Java,
y además Eclipse nos dirá que el XML está mal porque hay ids repetidos.
Nótese que no estamos definiendo el atributo “text” para los TextView. Esto es porque ya
hemos visto cómo se hace con el TextView que el ADT crea para nosotros, y queremos
que los alumnos vean cómo se asigna el texto a los TextView programáticamente.
Sin embargo, los alumnos pueden probarlo si desean.
Bajo el EditText del argumento B, necesitamos otro TextView, al que pondremos id
“tvResult” para mostrar los resultados, y tampoco le asignaremos atributo “text”. Bajo
este último TextView, añadimos este código para crear el Botón:

Ya tenemos lista la interfaz, y no tendremos que modificar más este archivo para que
nuestra aplicación funcione. Se recomienda arrancar la aplicación para ver cómo ha
quedado nuestra interfaz.

B.2. Código Java


Ya tenemos que entrar en nuestra única actividad. Vemos que en el constructor hay una
llamada a un método, el setContentView(), que es quien le dice a la Actividad que debe
coger el archivo main.xml y transformar el código XML en vistas (en inglés, “inflate the
views”). Lo que nosotros haremos es separar este código del constructor, y nos crearemos
un método privado:
Con este código, la aplicación funcionará exactamente igual que antes. Ahora
necesitamos que nuestra aplicación haga algo más que sólo mostrar vistas. Éstas son las
variables que vamos a declarar, y lo haremos justo encima del onCreate():

Lo primero, ¿qué es ese String?. Resulta que Android lleva un registro o “log” llamado
LogCat, donde se registran las operaciones que va realizando el Sistema Operativo.
Nosotros, los programadores de aplicaciones, podemos contribuir al LogCat escribiendo
en él, y para ello queremos identificar unívocamente cada clase que escribe en el LogCat, y
para eso es la etiqueta LOG_TAG. Podemos escribir por distintas razones, para
información, para advertencia, para errores, etc. Lo importante es no abusar de él.
Luego tenemos referencias a los distintos EditText y TextView, pero estas referencias
están vacías. Debemos unirlas o enlazarlas a las vistas del esquema. ¿Cómo hacemos esto?
Lo hacemos dentro del initConfig():

Como vemos, estamos llamando al método findViewById de la actividad para que nos
devuelva las referencias oportunas; tenemos que hacer un typecast al tipo de vista
específico. Como ejercicio, se deja la inicialización de textViewB, editTextB y result, que se
hacen justo debajo de la inicialización de action.
Después de esto, queremos poner texto a los TextView; para los dos primeros ya
escribimos los strings, luego sólo tenemos que llamar a los métodos oportunos.

Véase que para el textViewB hemos llamado al método getString() para transformar la
entrada XML en un String Java y que para el texto de result hemos escrito directamente la
cadena String. Dejamos a los alumnos inicializar textViewA utilizando el otro String
declarado en el XML y escribir directamente el texto del botón action.

Ya tenemos los textos, ahora necesitamos hacer algo. Primero, nos declararemos un
método privado que devuelve un entero con dos parámetros enteros, a y b, que tiene una
sola línea:

Lo que nosotros queremos es que se realice la operación de módulo cuando se pulse el


botón. Para que esto suceda, deberemos crear un objeto de tipo “OnClickListener” que
será llamado cuando el botón sea pulsado, y es en el método OnClick() de este objeto
donde pondremos el código de la operación. Esto lo haremos en initConfig(), justo antes
de la línea en la que escribimos en el LogCat:

El código en sí es bastante sencillo. Inicializamos un String para guardar el resultado,


cogemos los dos parámetros como cadenas de caracteres (es necesario el toString()
porque el método getText() devuelve un objeto de otra clase), los transformamos en
enteros, realizamos la operación módulo, y actualizamos el TextView de resultado. Ya
podemos ejecutar la aplicación, y veremos cómo realiza la operación módulo.
B.3. Problemas

A pesar de que funciona, la aplicación no está terminada. ¿Qué ocurre si intentamos


realizar el módulo de un número entre cero? ¿Y si introducimos números decimales?
Todos estos casos de uso son reales, y si no protegemos nuestra aplicación de ellos,
nuestros usuarios sufrirán de software de poca calidad. Antes de proseguir con la
resolución de estos problemas, sugerimos a los alumnos que coloquen un breakpoint
dentro del método onClick(), que ejecuten la aplicación en modo depuración, y vean paso
a paso cómo falla.

Tras el fallo, sugerimos que sea vea el resultado obtenido por el LogCat, donde se verá la
excepción producida.

Para protegernos de estos fallos, deberemos escribir código que actúe en caso de fallos,
como el módulo con cero o que insertemos números decimales. Esto se hace insertando
un bloque try/catch:

Nosotros no diremos qué parte del código del método onClick() va dentro del bloque
try, se lo dejamos a los alumnos, pero sí daremos el código del bloque catch:

Tras capturar la excepción, escribimos un mensaje de error en el Log para informar de


qué operación ha provocado el error, escribimos un mensaje en el TextView de resultado
y provocamos que aparezca una notificación de tipo Toast. ¿Qué es una notificación de
tipo Toast? Es una notificación que aparece durante un breve momento en pantalla, y que
sólo debemos utilizar cuando estemos seguros de que el usuario está concentrado en
nuestra aplicación, o no será perceptible. Con este código, podremos escribir lo que
queramos en los EditTexts, la operación fallará pero nuestra Actividad vivirá para contar
otra operación.

Ejercicio Básico A: Vistas y Layouts


En el primer ejercicio, construimos una aplicación sencilla entre todos paso a paso. En
este segundo ejercicio el objetivo es que empecemos a coger un poco de soltura
escribiendo código para aplicaciones Android, tanto XML como Java.

A. Descripción

En este ejercicio nos concentraremos en modificar solamente tres archivos de un proyecto


Android: la Actividad (Java), la interfaz (XML) y los textos (XML). Esto lo conseguiremos
añadiendo vistas (Views) a una aplicación por medio de XML, y luego nos conectaremos a
ellas a través de código Java para poder actuar cuando se produzcan eventos, como la
pulsación de un botón En el camino, iremos descubriendo nuevas vistas, además de
nuevas propiedades y listeners.

B. Implementación

Comenzaremos este ejercicio creando un nuevo proyecto Android desde Eclipse. Le


asignamos un nombre, le damos una versión (recomendamos 1.6 o mayor), un nombre a
la aplicación, a nuestro paquete (por ejemplo: com.[mi_nombre].android.apps.BasicoA) y
a la Actividad que queremos que se nos cree por defecto; finalmente ponemos un “3” en
el campo de versión mínima de SDK. Una vez le demos a Finalizar estaremos listos.

B.1. Primer layout

Vamos a comenzar editando el archivo de layout, el main.xml. En él tendremos ya la


estructura creada por defecto, en la que destaca un TextView con un texto.
Comenzaremos a trabajar añadiendo Views y ViewGroups bajo éste. Lo que queremos
hacer es un clásico checkbox para habilitar o no un ViewGroup, donde guardaremos una
vista. Debido a que también queremos practicar los eventos de las Views, necesitamos
también un TextView que acompañe al ya mencionado checkbox.

El código XML para poder añadir un CheckBox seguido de un TextView (main.xml) es el


siguiente:
Como vemos, hemos añadido dos Views, un CheckBox y un TextView. A ambas les hemos
dado un id, para poder referenciarlas desde el código Java, y les hemos puesto las mismas
características de anchura y altura.

El CheckBox viene acompañado de un TextView internamente, ahorrándonos la tarea de


tener que añadirlo nosotros para que sea intuitivo de usar. Para poder asignarle un texto
solamente tenemos que utilizar la propiedad text. Por último, hemos puesto por defecto
que el CheckBox no esté marcado (checked=”false”) En el caso de que queramos tenerlo
marcado por defecto solamente tenemos que ponerlo a true. El TextView es muy sencillo.
Las dos únicas propiedades que asignamos son número mínimo de líneas y número
máximo de líneas, de forma que tenga altura suficiente para mostrar dos líneas de texto.
Es una forma para “forzar” al TextView a que tenga la altura que queremos, pero no la
mejor.

Con esto ya tenemos un interruptor y un lugar donde escribir. Ahora nos hace falta un
LinearLayout que nos guarde las vistas con las que vamos a practicar un poco. Realmente,
este Layout que vamos a añadir no es necesario, pero lo usamos para aprender. El código
que sigue al último TextView (el eventsTextView) y que termina antes del cierre del
LinearLayout principal (o raíz), es el siguiente:
A este LinarLayout le hemos dado un id, y le hemos asignado unas características de
anchura y altura similares a las Views que hemos visto antes. Le hemos dicho que
queremos que nos coloque las Views una debajo de otra (orientation=”vertical”), y le
hemos dado un padding. El padding es una distancia que separa una View/ViewGroup
cualquiera del marco en el que está situada. En este caso, hemos puesto un padding de
7dp (“dp” se explicará en un ejercicio posterior, por ahora interpretar que son píxeles), es
decir, un margen de 7 píxeles respecto a las 4 esquinas. El padding o margen no tiene por
qué ser general; también puede ser respecto a una esquina o lado en concreto.

Para terminar con el LinearLayout, tenemos la propiedad visibility puesta a “gone”.


Como si nombre indica, la propiedad visibility determina si el LinearLayout es visible o no,
y lo interesante es que si el LinearLayout no es visible, sus hijos no lo serán, aunque éstos
sean visibles. Una View tiene tres posibles estados de visibilidad: “visible” (por defecto),
“invisible” y “gone”. “Visible” es auto-explicatorio, y la diferencia entre “invisible” y
“gone” la veremos en el último apartado.

Para terminar aquí, tenemos el RadioButton, que es hijo de nuestro nuevo LinearLayout.
Un RadioButton es un botón especial; deriva de la clase Button, y se parece mucho a un
CheckBox, salvo por una cosa: el CheckBox puede funcionar como interruptor (apagado /
encendido o viceversa), pero el RadioButton no. El RadioButton, una vez marcado, no
puede desmarcarse. Por lo demás, su declaración no contiene nada nuevo.

Ahora lo ideal sería marcharnos a modificar código Java, pero no podemos. Como Eclipse
ya os habrá avisado, existen errores que debemos solucionar. Si todo ha marchado bien,
los errores provienen de las propiedades text, que referencian a una cadena (string) del
archivo strings.xml que aún no hemos añadido. Por tanto, vayámonos al archivo
strings.xml y dejémoslo como está aquí:

Con este código XML, los errores del main.xml deberían desaparecer. Ahora, por fin,
podemos empezar con Java.

B.2. Java y eventos

Abrimos nuestra Actividad, y lo primero que haremos es preparar las cosas como a
nosotros nos gustan: nuestro método initConfig(). Comenzaremos dejando el código de
nuestra Actividad (lo que va dentro de la definición de la clase) como vemos aquí:

Como se observa, el grueso de nuestro código se coloca dentro del método initConfig().
Sin embargo, antes de empezar, necesitamos declarar las variables que vamos a utilizar.
Para ello, añadimos el siguiente código justo antes del método onCreate():
Éstas son las cuatro referencias que vamos a necesitar. Lo siguiente es inicializar las
variables en el método initConfig():

Sin duda, éste es un buen momento para arrancar la aplicación. Al hacerlo, vemos
nuestro CheckBox, y al tocarlo vemos que se marca y que se desmarca, pero no ocurre
nada más. ¿Qué es lo que queremos que ocurra? Pues que el LinearLayout se vuelva
visible si el CheckBox está marcado. ¿Cómo lo hacemos? Con un listener:

Este listener nos da como parámetros el botón en cuestión, que no nos hace falta, y un
boolean con la situación actual sobre si está marcado o no. Es importante tener presente
que esta llamada se produce después de que el CheckBox cambie de estado, no antes. Lo
único que debemos hacer es cambiar el estado de visibilidad según el booleano, a “visible”
o a “gone”. Con esto, ya deberíamos conseguir nuestro objetivo: que sea vea y que no sea
vea el RadioButton. ¿Qué nos queda? El propio RadioButton:
Probemos ahora. Vemos que funciona perfectamente, pero se nos formula otra pregunta,
y es, ¿cuántas veces se ejecuta este listener? Averiguarlo es muy fácil. Lo primero es
declarar una variable de tipo int, por ejemplo clickTimes; la declaramos como privada
debajo de las demás variables, justo encima del método onCreate(). Luego, alteramos el
código del listener, añadiendo una línea antes para inicializar clickTimes a cero:

Es importante señalar que la línea clickTimes = 0 se ejecuta una sola vez, pero el código
que está dentro del setOnCheckedChangeListener se ejecuta cada vez que el RadioButton
cambie de estado, que es lo que nos promete este listener. Solamente tenemos que
ejecutar este código para probarlo. Si de verdad quisiéramos contar cuántas veces
hacemos click en el RadioButton, lo único que tendríamos que hacer es cambiar de
listener, y utilizar el onClickListener, que se ejecuta una vez por cada click,
independientemente de si se cambia de estado o no:
B.3 Visibilidad

El último apartado de este ejercicio es también el más corto. Aquí, finalmente,


descubrimos la diferencia entre que una View tenga visibilidad “invisible” o “gone”. Para
ello, debemos volver al main.xml, y añadir una nueva View, justo donde lo dejamos antes,
es decir, tras el cierre (</LinearLayout>) del Layout que guarda al RadioButton. Éste es
el código a añadir:

El ToggleButton es una mezcla (a nivel de concepto) entre el CheckBox y el Button


convencional. Básicamente, es un botón clásico con estado, donde una luz nos indica si
está marcado o no. Visualmente, se parece mucho más a un interruptor que un CheckBox,
pero a nivel práctico (de programación, no así para el usuario) son lo mismo. La primera
novedad es que no hemos declarado que ocupe todo el ancho de la pantalla, lo cual nos
da pie para la nueva propiedad que vemos allí, layout_gravity. Lo que nos permite
layout_gravity es decirle al contenedor (padre) de una View dónde quiere que nos
coloque en el caso de que no ocupemos todo el espacio que podemos ocupar. Por
ejemplo en este caso, ninguna otra View se colocará a la misma altura de este
ToggleButton, por lo que nosotros hemos decidido que queremos que esté en el centro.
Después tenemos que la propiedad text está dividida en dos casos aquí, una para cuando
el botón esté presionado o marcado (textOn), y otra para cuando no lo está (textOff).
Como siempre, si todo ha ido bien, los errores que tendremos serán porque nos falta
declarar las dos cadenas en el archivo strings.xml:

Ahora volvemos al código Java, que es donde se producen los cambios. ¿Qué queremos
con el botón? Muy sencillo: siempre y cuando el CheckBox no esté activo, si el
ToggleButton está apagado la visibilidad de myLinearLayout será “gone”, y si está
activado será “invisible”. Los dos siguientes pasos os los dejamos a vosotros: declarar la
variable ToggleButton toggleVisibility y unirla con la View de la interfaz XML.

Por último, y ya para terminar, añadimos este código al initConfig(), y habremos


terminado:

También podría gustarte