1. M.Sc(c) Jaime Caicedo Guerrero
DESARROLLO DE APLICACIONES
PARA DISPOSITIVOS MOVILES
M.Sc (c). Jaime Caicedo Guerrero
jcaicedo@unicauca.edu.co
2. M.Sc(c) Jaime Caicedo Guerrero
Introducción
• Actividad (android.app.Activity) -> unidad básica de
funcionalidad de una aplicación Android.
• Para darle a las Actividades presencia en la pantalla y
diseñar su interfaz de usuario, hay que trabajar con
vistas (Views) y grupos de vistas (Viewgroups),
unidades básicas de la interfaz de usuario en la
plataforma Android.
3. M.Sc(c) Jaime Caicedo Guerrero
Introducción
Vistas (View)
• Una vista es un objeto de clase base android.view.View. Es una
estructura de datos cuyas propiedades guardan la disposición y
contenido para un área rectangular específica de la pantalla. Un
objeto vista (View) maneja la medida y disposición, dibujado,
cambio de foco, scroll y pulsaciones de teclas para el área de
pantalla a la que representa.
• La clase View sirve como clase base para los widgets, un conjunto
de subclases completamente implementadas que dibujan
elementos interactivos en la pantalla. Los widgets manejan sus
propias medidas y forma: Text (Para mostrar texto), EditText (Para
que el usuario introduzca texto), Button (Botón), RadioButton (Para
seleccionar una opción de un grupo de ellas),Checkbox (Para
seleccionar una o más opciones de un conjunto.) …
4. M.Sc(c) Jaime Caicedo Guerrero
Introducción
Grupos de vistas (Viewgroup)
• Un grupo de vistas es un objeto de la
clase android.view.Viewgroup. Como su nombre indica, un
grupo de vistas es un tipo especial de objeto Vista cuya
función es contener y organizar un subconjunto de vistas y
otros grupos de vistas. Los grupos de vistas permiten añadir
estructura a la interfaz de usuario y construir elementos de
pantalla complejos que puedan ser referenciados como una
sola entidad.
• La clase Viewgroup sirve como clase base para los layouts, un
conjunto de subclases implementadas que ofrecen tipos
comunes de disposiciones en pantalla. Los layouts ofrecen
una forma de construir una estructura para un conjunto de
vistas.
9. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets básicos
• Campos de chequeo -> Checkbox
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Este campo de chequeo se encuentra: unchecked" />
Algunos métodos importantes:
isChecked() determinar el estado del Checkbox
setChecked() fijar el estado del Checkbox
toggle() chequear el Checkbox, simulando una
acción del usuario
CheckBoxExample.java
10. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets básicos
Botones de selección-> RadioGroup, RadioButton
<RadioGroup
xmlns:android="http://schemas.android.com/apk/r
es/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RadioButton android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rock" />
<RadioButton android:id="@+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Salsa" android:checked="true"/>
<RadioButton android:id="@+id/radio3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pop" />
</RadioGroup>
Algunos métodos importantes:
check() chequear un RadioButton a través de su ID
clearCheck() clarear todos los Radio Buttons
getCheckedRadioButtonId() obtener el Id del radioButton
chequeado(-1 si ninguno se encuentra seleccionado)
RadioButtonExample.java
11. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
Alojan varios componentes de Vista (View) o Grupos de
Vista (ViewGroup). Clase ViewGroup.LayoutParams
12. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
LinearLayout
Los componentes son “alineados” en una columna o fila, uno
detrás de otro. Gestiona las siguientes propiedades:
• Orientation: Si representa una columna o fila
(android:orientation _horizontal|vertical).
• Fill Model: Hace referencia al llenado del espacio del
componente.(android:layout_width,android:layout_height):
– wrap_content: El componente debe llenar su espacio naturalmente.
– fillparent: - el componente debe llenar el espacio restante en el
contenedor
• Weight: prioridad en la repartición de espacio entre dos o
más componentes.
13. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
LinearLayout
• Gravity: alinear el componente de forma diferente a sus valores por
defecto (left, top-aligned) (android:layout_gravity).
• Padding: incrementar el espacio por defecto entre los componentes
(android:padding).
LinearLayoutExample.java
14. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
RelativeLayout
Organiza los widgets con relación al contenedor padre o con
relación a otros widgets.
• Posiciones relativas al contenedor:
– android:layout_alignParentTop – parte alta del contenedor
– android:layout_alignParentBottom – parte baja del contenedor
– android:layout_alignParentLeft - lado izquierdo del contenedor
– android:layout_alignParentRight – lado derecho del contenedor
– android:layout_centerHorizontal – horizontalmente en el centro del
contenedor
– android:layout_centerVertical – verticalmente en el centro del
contenedor
– android:layout_centerInParent – horizontal y verticalmente en el
centro del contenedor
15. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
RelativeLayout
• Posiciones relativas a otros widgets:
Se requiere definir id para todos los componentes. Un widget B se puede
referir a un widget A con id @+id/widget_a a través de @id/widget_a.
– android:layout_above – arriba del widget referenciado
– android:layout_below – abajo del widget referenciado
– android:layout_toLeft – a la izquierda del widget referenciado
– android:layout_toRight – a la derecha del widget referenciado
– android:layout_alignTop – alinear parte alta widget A – parte alta widget B
– android:layout_alignBottom – alinear parte baja widget A – parte baja widget B
– android:layout_alignLeft – alinear izquierda widget A – izquierda widget B
– android:layout_alignRight - alinear derecha widget A – derecha widget B
– android:layout_alignBaseline – alínear líneas de base de los widgets
– android:layout_toRight – alinear a la derecha del widget referenciado
RelativeLayoutExample.java
16. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
TableLayout
Permite posicionar los widgets en una tabla de acuerdo a la elección del
desarrollador. Trabaja con un contenedor interno: TableRow.
Existe control absoluto sobre la definición de filas; las columnas son
gestionadas por Android y se tiene un control indirecto.
• Algunas propiedades útiles:
– android:layout_span – número de columnas que puede ocupar un widget
– android:layout_column – fijar la columna de inicio de un widget
– android:stretchColumns – expandir una o más columnas para usar el espacio
sobrante (contenido ocupa menos espacio que el disponible) ->
setColumnStretchable().
– android:shrinkColumns – comprimir una o más columnas para utilizar el espacio en
pantalla (contenido ocupa más espacio que el disponible) ->
setColumnShrinkable().
– android:collapseColumns – ocultar una o más columnas -> setColumnCollapsed().
TableLayoutExample.java
17. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Contenedores
ScrollView
Variante de TableLayout.
Proporciona capacidades de scrolling para el contenido en la
pantalla.
Mantiene la integridad en la información de la tabla, pero sólo se
visualiza una parte de la misma.
ScrollViewExample.java
18. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• Premisa básica: los elementos de selección son
preferidos sobre los elementos de ingreso de texto,
pese a las capacidades de restricción de contenido
que éstos pueden ofrecer.
• Android ofrece un conjunto de adaptadores de datos
que ofrecen una interfaz de datos común para
alimentar el contenido de este tipo de widgets.
Convierten los datos en datos visibles a través de
vistas de selección.
19. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
Uso de ArrayAdapter:
• Parámetros:
– El Contexto a utilizar (típicamente la instancia de la
Actividad actual).
– El Id del recurso de la vista a usar
– El arreglo de items de datos que se va a utilizar
20. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
Instanciación de ArrayAdapter: (override del método
getView)
• Parámetros:
– Index del item en el arreglo que se desea desplegar en la vista
– Una vista existente para actualizar los datos en la posición
deseada.
– El widget que contendrá la vista
21. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• ListView -> control ListBox clásico en Android
La actividad puede extender
de ListActivity en lugar de
Activity.
El método SetListAdapter(),
permite fijar el ArrayAdapter
que se desea utilizar.
ListViewExample.java
22. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• SpinControl -> control ComboBox clásico en Android
setDropDownViewResource()
enlace a un recurso específico
para configurar la apariencia del
control.
SpinnerExample.java
23. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• GridView -> Vista de selección en dos dimensiones
Algunas propiedades:
• android:numColumns: número de columnas
(autofit -> ajuste automático)
• android:verticalSpacing,
android:horizontalSpacing: controla el espacio
entre los items de la grilla.
• android:columnWidth: indica el ancho de las
columnas.
24. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• GridView -> Vista de selección en dos dimensiones
GridViewExample.java
25. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• AutoCompleteView -> Híbrido entre EditView y
Spinner con propósitos de predicción de Texto.
AutoCompleteViewExample.java
<AutoCompleteTextView
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="3"/>
No soporta listeners de selección
Sugerencia: Registro de un TextWatcher
26. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• Gallery -> Control de lista desplazable
horizontalmente. (Uso frecuente: galería de fotos)
GalleryExample.java
<Gallery
android:id="@+id/galleryCtrl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Manejo similar a una lista:
1. Se obtiene una referencia al Gallery
2. Se fija el adaptador para los datos
3. Se registra el manejo de eventos
27. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• Mejorando el widget ListView
– Cómo adicionar íconos a la lista?
La clave está en la
modificación del
ArrayAdapter!
IconListViewExample.java
28. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de selección
• Mejorando el widget ListView
– Qué sucede si se requiere varios tipos de íconos? O
– No todas las filas usan el mismo layout (algunas una línea de
texto, otras dos)?
El concepto de Inflación (“Inflation”): convertir la especificación
de un layout XML en el árbol de objetos View que representa.
Concepto implementado internamente por Android a través de
la clase “ViewInflate”. Permite la manipulación de cada objeto
View del layout para dar la apariencia buscada.
MultipIeIconListViewExample.java
29. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de Fecha/Hora
• DatePicker, DatePickerDialog
– Introducción de fecha en el formato año, mes (0 - 11), día.
– Proporciona un objeto callback OnDateSetListener que
informa sobre una nueva fecha seleccionada por el
usuario.
• TimePicker, TimePickerDialog
– Fijar la hora en el formato Hora (0 - 23), Minuto (0 - 59).
– Fijar el formato de la hora (AM/PM – 24H)
– Proporciona un objeto callback OnTimeSetListener que
informa sobre una nueva hora seleccionada por el usuario.
31. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Widgets de Fecha/Hora
• DigitalClock, AnalogClock
– Diseñado con propósitos de despliegue de fecha/hora y no
de introducción de información.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/a
ndroid"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<AnalogClock android:id="@+id/analog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>
<DigitalClock android:id="@+id/digital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/analog"
/>
</RelativeLayout>
ClockExample.java
32. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Tabs
• Facilita el despliegue de información a través de varias pantallas
gestionadas por la actividad (pestañas).
Componentes:
TabWidget: Implementa la fila de tab
buttons (incluye labels y
opcionalmente íconos).
TabHost: Contenedor para los
botones de los Tabs y el contenido de
los mismos.
FrameLayout: Contenedor para el
contenido de los Tabs.
33. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Tabs
Algunas reglas básicas:
• El TabWidget debe tener un identificador de la forma
@android:id/tabs.
• Evitar el padding en el FrameLayout para los tab buttons
• Si se desea usar la clase TabActivity el TabHost debe
tener un id de la forma @android:id/tabhost.
34. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Tabs
Construcción de los Tabs:
El código Java debe informar al TabHost qué vistas corresponden al
contenido de los tabs y cómo deben lucir los tab buttons -> objetos
TabSpec.
Métodos esenciales:
• setContent(): inidica el contenido del tab (android:id de la vista
específica).
• setIndicator(): proporciona las etiquetas para los tab buttons
(opcionalmente se incluye un drawable para representar íconos).
• setup(): método invocado en el TabHost (no requerido si la clase
base de la actividad es TabActivity)
36. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Menús contextuales
• Información adicional asociada a un widget
específico.
• Dos sabores: Menú de opciones (accesible
al presionar el botón hardware del
dispositivo), Menú contextual (presionar y
sostener sobre el widget que lo despliega).
• Creación del menú: onCreateOptionsMenu() -> recibe una instancia
de Menu.
• super.onCreateOptionsMenu(menu) -> Asegurar que el framework
Android adicione las opciones necesarias.
37. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Menús contextuales
• Adición de opciones al Menú -> método add ().
– Un identificador de grupo (int): generalmente 0.
– Un identificador para la opción (int): identificar la opción
seleccionada durante un callback a
onOptionsItemSelected().
– Etiqueta para la opción.
– Los identificadores de la opción deben ser referidos a la
constante FIRST.
38. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Menús contextuales
• Vinculación del menú al widget
– El menú está asociado a un widget y no a una actividad
específica.
– onPopulateContextMenu(): permite fijar el contenido del
menú y asociar la Vista (View) correspondiente.
– onContextItemSelected(),onOptionsItemSelected():
permite acceder a la información cuando una opción del
menú es seleccionada. Implementado en la Actividad.
40. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Mensajes y Alertas
• Usados generalmente con propósitos de notificación.
• Dos tipos de mensajes definidos por Android:
– Toast: mensaje transitorio (tiempo fijo), desaparece sin
intervención del usuario.
– AlertDialog: mensaje de diálogo estilo modal (requiere la
intervención del usuario para desaparecer la pantalla).
41. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Mensajes y Alertas
Toast:
• Se configura a través del método estático makeText():
– Contexto: actividad a la cual está asociado.
– Cadena del mensaje: (String)mensaje a ser desplegado (opc.
resource id).
– Duración: referido a las constantes LENGTH_SHORT y
LENGTH_LONG
• show(): despliega el toast.
42. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Mensajes y Alertas
AlertDialog:
• Construido a partir de la clase Builder:
– setMessage(): cuerpo del mensaje.
– setTitle(), setIcon(): texto del título e ícono asociado al
diálogo.
– setPositiveButton(), setNeutralButton(), and
setNegativeButton() : configuración general del botón del
diálogo (etiqueta, lógica de la acción).
– show(): desplegar el diálogo.
44. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Barras de progreso
Introducción al manejo de Threads
• Operaciones que consumen altos recursos de
procesamiento -> interfaces congeladas.
• Android proporciona un conjunto de medios que
permite a hilos en background interactuar de forma
segura con el UI Thread:
• Objetos Handler, Runnable y UIThreadUtilities.
45. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Barras de progreso
Introducción al manejo de Threads
• Handlers
– Sólo se requiere un Handler por Actividad y no se requiere
un registro manual.
– El hilo en background puede comunicarse con el Handler,
el cual realizará todo su trabajo en el UI Thread de la
Actividad (las actualizaciones de los widgets ocurren en
este hilo).
– Dos formas de comunicarse directamente con los
Handlers: objetos Message y Runnable.
46. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Barras de progreso
Introducción al manejo de Threads
• Handlers
– Primer paso: obtener un manejador del pool de mensajes ->
obtainMessage().
– Enviar el mensaje a través de la familia de métodos disponibles:
– sendMessage(): pone un mensaje en el pool de forma
inmediata.
– sendMessageAtFrontOfQueue(): pone un mensaje en el pool de
forma inmediata y prioritaria.
– sendMessageAtTime(): pone el mensaje en el pool en el tiempo
fijado.
– sendMessageDelayed(): pone el mensaje en el pool, después
del retardo fijado.
– El Handler debe implementar handleMessage() para gestionar
el arrivo de mensajes en el pool.
47. M.Sc(c) Jaime Caicedo Guerrero
Android UI – Barras de progreso
Fijando un Handler para gestionar una barra de progreso
ProgressBarExample.java
48. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Introducción a los Intents
• Forma de representar una acción a través de mensajes.
• La forma de comunicación en Android funciona
alrededor de “intents” y receptores de “intents”.
URL GET
Recurso Acción
+ Contexto Acción
Android Intents
+
La Web
49. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Introducción a los Intents
• Dos componentes principales: la “acción” y los “datos”.
• Otros criterios que pueden agregarse:
– Una categoría: la actividad principal está en la categoría
LAUNCHER, indicando que debe ser accesible desde el menú
principal desde donde se lanzan las aplicaciones. Otras
actividades pueden pertenecer a categorías como DEFAULT o
ALTERNATIVE.
– Un tipo MIME: indicando el tipo de recurso sobre el cual se
desea operar.
– Un componente: la clase de la actividad que actúa como
receptora del intent.
– Extras: conjunto (Bundle) del que hace parte cualquier otra
información que se desee enviar al receptor del Intent.
51. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Introducción a los Intents
Algunas reglas básicas:
• La actividad debe soportar la acción especificada.
• La actividad debe soportar el tipo MIME establecido.
• La actividad debe soportar las categorías
establecidas en el Intent.
Intent filters
52. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Introducción a los Intents
• Intent filters
Actividad principal de
la aplicación
Accesible desde el
menú principal
53. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Uso de Intents para navegación entre pantallas
• Construir el intent: haciendo referencia a la
Actividad específica que se desea lanzar o a una URI.
• Realizar el llamado: invocar el método startActivity()
referido al intent creado.
54. M.Sc(c) Jaime Caicedo Guerrero
Android UI - Navegación
Uso de Intents para navegación entre pantallas
NavigateList.java
NavigateClock.java
Servidor
Proxy?
55. M.Sc(c) Jaime Caicedo Guerrero
Android – Carga del emulador usando Proxy
Importante: Si el acceso a Internet por parte del emulador se
da a través de un servidor proxy, esta configuración debe ser
realizada durante el lanzamiento del emulador de la
siguiente manera:
C:android-sdk-windowstools>emulator -avd Default -http-proxy
http://proxy.unicauca.edu.co:3128