feb
21
2011

Montando la Interfaz Gráfica en Android, Parte II

Eventos

Android proporciona varias formas de capturar los eventos ejecutados por el usuario en su interacción con la aplicación.

Event Listeners

Un event listener es una interface de la clase View que contiene un método que se será llamado por el framework de Android cuando el listener que ha sido registrado es lanzado por la interacción del usuario con el elemento del UI.

onClick(). Es llamado cuando el usuario pulsa el elemento (touch mode) o se sitiúa sobre éste con las teclas de navegación o el trackball y presióna la tecla “enter”.

onLongClick(). Es llamado cuando el usuario pulsa sobre el elemento de manera prolongada.

onFocusChange(). Es llamado cuando el usuario navega dentro o fuera de un elemento, usando las teclas de navegación o el trackball.

onKey(). Se llama cuando el usuario sitúa el foco en un elemento y presiona una tecla en el dispositivo.

onTouch(). Se llama cuando el usuario realiza una acción calificada como touch event, incluyendo presionar, soltar o cualquier movimiento dentro de los límites del elemento.

onCreateContextMenu(). Se llama cuando un Context Menu se muestra en pantalla.

El botón se conecta a su comportamiento a través del método setOnClickListener, que viene heredado de la interface OnClickListener que implementa la clase Activity.

class GuiEvent extends Activity {
	@Override public void onCreate (Bundle state){
		super.onCreate(state);
		setContentView (R.layout.main);

		final EditText et1= (EditText) findViewById (R.id.text1);
		final EditText et2= (EditText) findViewById (R.id.text2);

		((Button)) findViewById(R.id.button2)).setOnClickListene{
			new Button.OnclickListener{
				Random rand =new Random();
				@Override public void onClick (View arg0){
					et1.setText(String.valueOf(rand.nextINT(200)));
					et2.setText(String.valueOf(rand.nextINT(200)));

				}
			}
		}
	}
}

A su vez OnClickListener define un único método onClick que cuando un botón recibe un evento del framework lo examina observando si está cualificado como “click” y en ese caso ejecuta dicho método.

Un click se puede realizar de distintas maneras dependiendo del dispositivo, pero el framework se encarga de gestionarlo y solamente nos tenemos que preocupar de controlar el evento a su nivel más alto.

Event Handlers Cuando se crea un componente personalizado extendiendo de una View, se pueden definir una serie de métodos que gestionan los eventos por defecto.

onKeyDown(int, KeyEvent). Llamado cuando un evento pulsar teclado ocurre.

onKeyUp(int, KeyEvent). Llamado cuando un evento soltar teclado ocurre.

onTrackballEvent(MotionEvent). Llamado cuando un evento trackball ocurre.

onTouchEvent(MotionEvent). Llamado cuando un evento tocar pantalla ocurre.

onFocusChanged(boolean, int, Rect). Llamado cuando un elemento gana o pierde el foco.

Touch Mode

Para terminales táctiles, una vez que el usuario pulsa sobre la pantalla el dispositvo entra en touch mode. Sólo las Views que tengan isFocusableInTouchMode() a verdadero se pueden pulsar.

Touch Mode

El framework maneja las rutinas referidas al movimiento del foco entre Views en respuesta de las entradas del usuario. Las Views indican su posibilidad de adquirir el foco mediante el método isFocusable(). Para forzar que un elemento pueda capturar el foco se llame a setFocusable().

Notificaciones

Se utilizan en situaciones en las que se requiere notificar al usuario que ha ocurrido un evento en la aplicación.

Existen varias formas de mostrar estas notificaciones:

Toast Notification: para mostrar mensajes breves.

Toast

Status Bar Notification: para recordatorios que necesitan una respuesta del usuario.

Status_Bar

Dialog Notification: relacionadas con información mostrada por las Activity.

Dialgo

Asociando datos a vistas AdpaterView

El AdapterView es un clase que hereda de ViewGroup, cuyos clases hijas se inicializan a través de un objeto Adapter que asocia a la vista cualquier tipo de información. Ejemplos de AdapterViews son Gallery (muestra una colección de imágenes), ListView (listado de datos), and Spinner (similar a un desplegable) que disponen un tipo específico de datos de un modo determinado.

Las dos principales utilizaciones de estos objetos son:

Rellenar el layout con datos:

Hecho a través de la asociación de la clase con un Adapter que toma los datos de alguna fuente: una lista que el código suministra o el resultado de una consulta a una base de datos del dispositivo

	private String [ ] frutas ={"manzanas","naranjas","limones"};
	Spinner s1 =(Spinner) findViewById (R.id.listafrutas);

	s1.setAdapter (new ArrayAdapter<String>(this, R.layout.spinner_1, mStrings));

Manipular las selecciones del usuario

Esto es hecho al asignar al miembro “AdapterView.OnItemClickListener” de la clase un objeto escuchador de eventos y capturar los cambios que el usuario hace en su selección.

private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
		public void onItemClick(AdapterView parent, View v, int position, long id) {
			// Display a messagebox. showAlert("You've got an event", "Clicked me!", "ok", false);
		}
	};

Objetos comunes de un Layout

FrameLayout Es el layout más sencillo. Está diseñado como un espacio en blanco reservado en la pantalla que posteriormente se puede rellenar con un único objeto. Todos los elementos hijos son posicionados en la parte superior izquierda de la pantalla.

LinearLayout

Alinea todos sus elementos hijos en una única dirección: vertical u horizontal, de acuerdo a la propiedad que se ha definido. Todos los hijos son ubicados uno al lado del otro, por lo tanto una lista vertical sólo tendrá un hijo por fila sin importar lo ancha sea la fila.

TableLayout

Posiciona sus hijos dentro de filas y columnas. Un TableLayout está compuesto por un número de objetos TableRow, cada uno de ellos definiendo una fila.

AbsoluteLayout

Permite que los elementos hijos especifiquen con precisión las coordenadas “x” e “y” en la cual deben ser desplegados. La posición (0,0) corresponde a la esquina superior izquierda.

RelativeLayout

Permite que sus elementos hijos especifiquen su posición relativa entre ellos(indicando un ID) o con su padre.

layout

0
ene
31
2011

Montando la Interfaz Gráfica en Android, Parte I

El framework UI de Android proporciona tanto herramientas de dibujo, con las que construir la UI, como una rica colección de elementos ya creados.

Los componentes finales del árbol de vistas, que conforman la mayor parte de los elementos que se muestran en el contexto de una aplicación UI, se conocen como widgets.

Los nodos, llamados Container Views, son aquellos que pueden tener otros componentes como hijos y son derivados de la clase android.view.ViewGroup.

Un ViewGroup normalmente apenas realiza ningún dibujo y es responsable de situar a sus hijos en la pantalla, manteniéndolos en su sitio mientras que el dispositivo cambia de forma o de orientación.

Android nos ofrece la posibilidad de crear la “fachada” de la aplicación mediante ficheros XML. De esta forma, nos podemos concentrar en el aspecto funcional de la aplicación (código Java) o puramente estético (XML).

También se puede generar la interfaz mediante código Java, pero es mucho más correcto y ordenado usando lo que Android nos ofrece.

En la carpeta “res”, se almacenan todos los recursos del sistema. Dentro de estos recursos están nuestros archivos XML que usaremos para crear las vistas de nuestra aplicación.

Declarando el Layout

1. Estilo Java

2. Estilo XML En esta versión de código también se preserva la referencia a la raíz del árbol de vistas.

Se etiqueta al widget en el layout XML con android:id y se recupera la referencia desde el código con el método findViewById de la clase Activity.

Menús

Los menús proveen al usuario de información sobre funciones y configuraciones a cerca de la aplicación.

Existen diferentes tipos de menús dependiendo de las necesidades de cada situación.

Options Menu

Es el primer conjunto de elementos de menú para un Activity. Se muestra presionando la tecla MENU del dipositivo. Se divide en dos grupos de elementos:

Menú de iconos: permite un máximo de cinco elementos y se pueden añadir iconos. Menú extendido: es un listado vertical de elementos que se crea al existir más de cinco elementos.

Se muestra al pulsar sobre “Más”.

Al ser llamado por primera vez, el sistema ejecutará la función onCreateOptionsMenu()que se sobreescribe para proporcionar la funcionalidad que se requiera.

Los elementos de un menú se pueden añadir a través de la función add() que crea objetos MenuItem o utilizando un fichero XML definido en el directorio menu de la aplicación.

Cuando un elemento es seleccionado se realiza una llamada al método onOptionsItemSelected() que recibe el MenuItem relacionado. Dicho elemento se puede identificar a través de getItemId(), que devuelve el entero que le fue asignado con el método add()

Cxontext Menu Es parecido al evento “click-derecho” en un ordenador.

Cuando una View registra un menú de este tipo, si se presiona durante un tiempo sobre el objeto, revela un menú flotante que proporciona funcionalidad relacionada a dicho elemento.

Aunque se puede asociar a cualquier View es habitual hacerlo sobre los elementos de un ListView.

Para crear un menú contextual, se sobreescribien los métodos onCreateContextMenu() y onContextItemSelected().

Los elementos se añaden de igual forma que en el Options Menu. Para obtener información a cerca del elemento sobre el que se muestra el menú se solicita del AdapterContextMenuInfo asociado al objeto MenuItem. Finalmente se debe registrar el menú a la vista a través de registerForContextMenu(View).

Submenus

Se pueden añadir a cualquier menú, excepto a otro sub menú. Permite organizar las distintas funciones de una aplicación en temas. Para añadir un sub menú se utiliza la función addSubMenu().

Dialogs

Un Dialog es una pequeña ventana que aparece sobre la Activity que se está ejecutando capturando las acciones realizadas por el usuario.

Se utiliza normalmente para mostrar notificaciones y progresos de la aplicación al usuario. Para mostrar un dialogo se utiliza el método showDialog() indicando el indice que se le ha asignado

anteriormente en su incialización através del método onCreateDialog()

Si se desea cerrar el diálogo se puede descartar llamando a dissmis()del objeto Dialog o si es necesario se puede realizar a través del método dismissDialog(int) de la propia Activity.

Existen varios tipos de Dialogs:

AlertDialog

Esté tipo de Dialog puede uncluir de 1 a 3 botones, y una lista de elementos seleccionables que pueden incluir checkboxes o radio bttuons. Se pueden construir la mayor parte de las interfaces dialog de usuario y es el sugerido por la especificación.

ProgressDialog Hereda de AlertDialog y muestra una animación donde se muestra el progreso de una tarea que se está ejecutando.

Se pueden añadir botones que proveen funcionalidades requeridas por la aplicación.

El estilo por defecto de un dialogo de progreso es una rueda girando, se puede modificar el aspecto aplicando un estilo al dialogo.

Una Activity puede necesitar ejecutar un nuevo hilo donde se realizan operaciones y para ello debemos utilizar un objeto Handler que actualizará el diálogo de progreso.

Cuando enviamos un mensaje al Handler este lo guardará en una cola para que sea ejecutado por el hilo de la Activity.

DatePickerDialog

Permite al usuario seleccionar fechas.

TimePickerDialog
Permite al usuario seleccionar horas.

0
ene
07
2011

Gráficos 2D y Aplicaciones Multimedia

Las librerías android.graphics.drawable y android.view.animation son proporcionadas por Android para dibujar y animar imágenes y formas 2D.

Drawables

Se refiere a todo aquello que se puede dibujar. Es la clase de la cual heredan una variedad de tipos de gráficos, incluyendo BitmapDrawable, ShapeDrawable, PictureDrawable, LayerDrawable y otros. Hay tres maneras distintas de instanciar una clase Drawable.

- Utilizar una imagen almacenada en el directorio de recursos de nuestro proyecto.

- Utilizar un XML que define las propiedades del objeto para luego poder recuperarlo mediante getDrawable() y el ID que se le asignó en el XML.

– Utilizando los constructores propios de la clase.

Lxas librerías android.graphics.drawable y android.view.animation son proporcionadas por Android para dibujar y animar imágenes y formas 2D.

ShapeDrawable Se utiliza para realizar realizar gráficos simples en 2D y aplicarles estilos directamente

desde el código de nuestra aplicación.

Al ser una clase que hereda de Drawable, se puede utilizar en el mismo contexto que ésta. Se pueden realizar por lo tanto clases View que dibujen formas personalizadas gracias al métdo onDraw() que incluye la clase ShapeDrawable.

Se podría obtener directamente esta clase desde un XML layout haciendo que sobreescriba el constructor View(Context, AttributeSet), que es llamado cuando se instacia una View através de un XML.

NinePatchDrawable Es una imagen bitmap que Android puede redimensionar automáticamente para acomodar a los contenidos de la vista sobre la que se ha sitiado éste como background.

La imagen debe de ser de tipo PNG e incluir un borde de un 1 pixel de ancho y almacenado en el directorio res/drawable/ de nuestro proyecto con la extensión . 9.png.

Existe una herramienta tipo WYSIWYG dentro del SDK que nos permite generar imágenes de este tipo de un modo más fácil, llamado draw9patch.

Animaciones Android proprociona dos tipos de animaciones:

- Frame Animation: Es una animación tradicional creada con una secuencia de imágenes que se muestran en orden secuencial, como en una película. Se pueden definir cada fotograma por código a través de AnimationDrawable, aunque la forma adecuada es mediante un XML <animation-list> que define la imágen y la duración de cada secuencia, dentro del directorio res/anim/ de nuestro proyecto Android.

- Tween Animation: Permite realizar transformaciones simples de los contenidos de un objeto View. La secuencia de instrucciones se pude definir en código o mediante un XML (res/anim/ ), y definen qué, cuándo y durante cuánto tiempo va a ocurrir.

Las transformaciones pueden ser secuenciales o simultáneas.

Aplicaciones Multimedia

Android proporciona funciones de encoding/decoding para un gran número de tipos de medios, con lo que se pueden integrar fácilmente audio, video e imágenes en nuestras aplicaciones. La clase MediaPlayer permite reproducir audio y video de distinas fuentes, como ficheros en el directorio res/raw de nuestra aplicación o desde una conexión de red. Reproducir desde recurso local:

1. Almacenar el fichero en el directorio res/raw del proyecto, haciendo que el recurso pueda ser referenciado desde la clase R.

2. Crear una instancia de MediaPlayer y ejecutar el método start() pasando la referencia al recurso.

MediaPlayer mp= MediaPlayer.create(getApplicationContext (), R.raw.bundle);
mp.start();

Reproducir desde stream:

1. Crear una instancia de MediaPlayer y usar el método setDataSource()wcon la cadena que contiene el path al sitema local o la URL.

2. Utilizar prepare() y después start()en la instancia.

MediaPlayer mp = new MediaPlayer();
mp.setDataSource( PATH_TO_FILE);
mp.prepare();
mp.start();

La plataforma permite grabar audio y video cuando el dispositivo lo permite. Se utiliza la clase MediaRecorder.



0
ene
03
2011

Localización y Sensores

Android propociona una serie de clases incluidas dentro del paquete android.location y el la librería externa de Google Maps para poder realizar aplicaciones y servicios basados en localización y mapas.

Servicios de localización

El componente principal del framework de localización en el servicio del sistema LocationManager, proprociona un API para deterniminar la localización en dispositivos que lo permitan.

Al tratarse de un servicio, no se instancia la clase directamente, simplemente se realiza una llamada al sistema mediante el método getSystemService(Context.LOCATION_SERVICE) que nos proporcionará:

- Consultar la lista de LocationProviders conocidos.

- Registrar actualizaciones en la localización actual mediante el LocationProvider.

- Registrara un Intent que puede ser disparado cuando nos acercamos a una localización especificada.

Durante el desarrollo podemos, al no disponer de red GPS, la podemos emular através de un proveedor mock de localización.

GoogleMaps En el paquete com.google.android.maps proprociona funciones para descargar, mostrar y cachear mapas, así como una serie de vistas y controles. Existe una clase propia del API que hereda de ViewGroup y es la más importante y sobre la que se centran las distintas acciones com.google.android.maps.MapView.

 Un MapView muestra un mapa obtenido del servicio Google Maps.

Cuando se interactúa con la vista se pueden realizar acciones como el zoom y provee de elementos de UI necesarios para que el usuario pueda controlar el mapa con libertad.

Existen métodos propios de MapView que permiten trabajar através de programación

En general, la clase MapView provee un wrapper alrededor del API de Google Maps que proporciona a nuestras aplicaciones manipular la información utilizando sus métodos y trabajar con los mapas como si fuese una View cualquiera.

Sensores

Android permite acceder a los sensores internos del dispositivo a través de las clases Sensor, SensorEvent y SensorManager, y de la interface SensorEventListener, del paquete android.hardware. La clase Sensor acepta ocho tipos de sensores que varían en función del aparato utilizado.

Listar los sensores del dispositivo

 

Acceso a los datos del sensor

1
2
Sensor acelerometerSensor =listSensors.get(0);
mSensorManger.registerListener(mTop,acelerometerSensor, Sensor.SENSOR_DELAY_IU);

Para tener acceso a los datos del sensor debemos indicárselo al SensorManager con el método registerListener:

Es necesario registrar cada tipo de sensor por separado para poder obtener información de todos ellos. El método registerListener toma como primer parámetro la instancia de la clase que implementa el SensorEventListener, y que veremos a continuación. El tercer parámetro acepta cuatro posibles valores, que indican al sistema con qué frecuencia nos gustaría recibir actualizaciones del sensor. Esta indicación sirve para que el sistema estime cuánta atención necesitan los sensores, pero no garantiza una frecuencia concreta.

 

Cuando el evento se dispara en el método onSensorChanged comprobamos qué sensor lo ha causado y leemos los datos. Los posibles valores devueltos se indican en la documentación de la clase SensorEvent.

La clase SensorManager tiene además tres métodos (getInclination, getOrientation y getRotationMatrix), usados para calcular transformaciones de coordenadas.

0