Vous êtes sur la page 1sur 63

Puntos a recordar:

y y y

Todas las APIs o libreras son totalmente accesibles, si alguna aplicacin del smartphone puede hacer o tener acceder a algo entonces nosotros como programadores tambin. Se puede hacer mash-ups para combinar o trabajar con informacin de la web con informacin que hay en el smartphone, es decir mezclas entre aplicaciones. Las apps, utilizan varias piezas pequeas las cuales al juntarles formamos una app, es decir es como un rompecabezas. Todas las aplicaciones tienen la misma igualdad en Android, es decir las aplicaciones de terceros tiene la misma importancia a las apps que vienen desde por default en el smartphone. Dentro de Android hay una enorme flexibilidad de las aplicaciones, es decir podramos desarrollar una App que sea un Teclado Dvorak y hacer que se ejecute siempre que cualquier app requiera ingresar texto mostrando el Teclado Dvorak y no el Teclado Qwerty que tenemos por default en el dispositivo. Por cuestiones de seguirdad, en cada app que se desarroll se determinar qu tipos de permisos de uso se necesitan segn los objetivos de la aplicacin. Esto es para siempre avisar al usuario de qu informacin se har uso en la aplicacin y tendr la opcin de usar o no la aplicacin.

Ahora que ya tenemos instalado nuestro IDE, vamos a ver rpidamente qu es todo ese rbol que nos muestra el Explorador de Paquetes cuando creamos un nuevo proyecto Android.

AloMundo Esta es la carpeta con el nombre del proyecto segn como le hayamos nombrado. src Carpeta que contiene o almacena tu archivo Activity.

+ com.JC2life.alomundo * + MainAct.java gen Guarda l archi .java que se genrean por las herramientas de desarrollo de Android (A ) + com.JC2life.alomundo * + R.java Almacena un ndice de todos los recursos definidos en el proyecto, recomendable no modificarlo. assets Carpeta para el uso propio del usuario, ideal para almacenar cosas. Ojo que cada archivo lo comprimir en un .apk para su uso. res Carpeta para almacenamiento de imgenes y strings. + drawable-hdpi Para almacenar imgenes en alta resoluci n (para pantallas como el Galaxy , roid X, Atrix, etc). + drawable-ldpi Para almacenar imgenes en baja resoluci n (Motorola i1, Xperia MiniPro, etc). + drawable-mdpi Para almacenar imgenes en media resoluci n (Motorola Backflip, H C G1, etc). + layout Carpeta de los XM para los diseos de pantalla. + main.xml Aqu esta el diseo visual de tu programa. + values Carpeta par alos trings. + strings.xml XM para declarar las variables que usaremos en nuestra aplicaci n. AndroidManifest El manifiesto guarda metadatos e informaci n til de la aplicaci n para el O y almacena algunos o todos los bloques de construcci n de la aplicaci n (Actividad, Receptos de Intenciones, ervicios y Proveedores de Contenido). +info: Android Manifest default.properties Aqu guarda automticamente las propiedades del proyecto. * Este es el nombre del paquete (Package Name) y debe ser distinto a todos los existentes del mundo, se usa ms o menos como la metodologa de paquetes de Java, pero exactamente la forma es Dominio.NombreDueo.NombreAplicacin. En el ejemplo que estoy usando se puede decir que es de la aplicaci n AloMundo y el propietario es http://JC2life.com (esta website no existe). ino cuentas con un dominio te recomiendo que uses las iniciales de tu pas en el nombre del paquete, por ejemplo: mx.lopezdoriga.juayderito A la hora de hacer una aplicaci n podremos usar algunos o todos los bloques de construcci n (Actividad, Receptor de Intenciones, ervicios y/o Proveedores de Contenido) todos estos se llegan a definir dentro del AndroidManifest.xml

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/

17 Feb 10 Tutorial Android paso a paso I: Desarrollo de la aplicacin Notepad


Me he decidido a hacer una serie de posts a modo de curso para empezar a desarrollar aplicaciones para Android. Voy a omitir la instalaci n del entorno de desarrollo (eclipse + sdk android) ya que existen numerosos manuales disponibles en internet. e todas formas, para instalarlo recomiendo este enlace. espus seguiremos los manuales disponibles en ingls en la web oficial de Android (http://developer.android.com/resources/tutorials/notepad/index.html), pero en castellano y con pasos muy fciles de seguir (no ser una traducci n al pie de la letra). Nos deberemos descargar los ejemplos que encontraremos aqu para seguir el curso. Empezamos! Desarrollo de la aplicacin Notepad A travs de este tutorial vamos a crear una aplicaci n para tomar notas, que nos introducir a los aspectos bsicos y herramientas para el desarrollo en Android. Comenzando por un proyecto base, seguiremos los pasos para crear una simple aplicaci n, viendo como desarrollar la l gica de negocio y las interfaces, as como compilar y ejecutar la aplicaci n. En este ejercicio, vamos a construir una simple lista de notas, permitiendo al usuario aadir nuevas notas, pero no editarlas. Objetivos: Conocer istActivities y crear menus de aplicaci n. Utilizar Q ite para almacenar datos. C mo recuperar los datos de una base de datos y mostrarlos en pantalla. Conceptos bsicos sobre cmo interactuar con la interfaz de usuario. Paso 1 1. Crear un nuevo proyecto Android File > New > Android Project 2. En el cuadro de dilogo, seleccionar Create project from existing source 3. Pulsar Browse y navegar hasta donde hemos descomprimido el material del curso (carpeta NotepadCode ab) y seleccionar Notepadv1 4. as propiedades del proyecto deberan de completarse automticamente. 5. Pulsar Finish. El proyecto Notepadv1 debera abrirse y aparecer en el explorador de proyectos. i se produce algn error con AndroidManifest.xml, pulsar el botn derecho sobre el proyecto y seleccionar Android ools > Fix Project Properties.

Paso 2 Abrir el fichero notepad_list.xml en res/layout. Vamos a aadir los elementos necesarios para presentar la lista de notas. Podemos hacerlo de dos manera, aadir un istView y un extView desde el panel de elementos, o escribiendo el cdigo directamente en el XM .
1 2 3 4 5 6 7 8 9 10 11 12 13 <?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="wrap_content" android:layout_height ="wrap_content" > <ListView android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:id ="@android:id/list" ></ListView> <TextView android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:text ="@string/no_notes" android:id="@android:id/empty" ></TextView> </LinearLayout>

Los elementos que hemos aadido se mostrarn alternativamente, es decir, solo uno de ellos ser visible. Los identificadores list y empty son proporcionados por la plataforma Android, por lo que tenemos que aadir el prefijo android: a los identificadores (@android:id/list). La vista con el identificador empty, es usada automticamente por Android cuando no existen elementos que mostrar. Paso 3 Necesitamos mostrar las notas en el listado de notas, dentro del ListView. 1. Crear un nuevo fichero llamado notes_row.xml dentro de res/layout. 2. Aadir un nuevo extView a la interfaz. Aplicarle el siguiente identificador: @+id/text1 3. Guardar el fichero. Paso 4 Vamos a modificar la clase Notepadv1 para mostrar el listado de nostas y que nos permita aadir nuevas notas. Abrimos el fichero Notepadv1.java. ebemos cambiar la clase a la que extiende (Activity) por ListActivity. Esta clase nos proporciona funcionalidades extra para trabajar con listas. Vemos que existen varios mtodos en el cdigo: onCreate(): se ejecuta cuando se llama a la actividad (puede verse como un mtodo main). onCreateOptionsMenu(): crea el menu de la actividad. onOptionsItem elected(): se ejecuta al seleccionar un elemento del menu. Paso 5

Ahora que ya tenemos los componentes, ya podemos comenzar a construir la aplicacin. Lo primero que vamos a hacer es abrir/crear la base de datos y asignar el resultado a la vista (ListView). Vamos a aadir el siguiente cdigo al mtodo onCreate():
1 2 3 4 5 6 7 8 9 @Override publicvoid onCreate(Bundle savedInstanceState ){ super.onCreate(savedInstanceState ); super.onCreate(savedInstanceState ); setContentView (R.layout.notepad_list ); mDbHelper =new NotesDbAdapter (this); mDbHelper. open(); fillData(); }

Definir la siguiente variable a nivel de clase:


1 private NotesDbAdapter mDbHelper =null;

Hemos definido un nuevo mtodo, fillData(), que es el encargado de obtener todas las notas de la base de datos y asignrselas al ListView.
1 2 3 4 5 6 7 8 9 privatevoid fillData(){ Cursor c = mDbHelper. fetchAllNotes (); startManagingCursor (c); String[] from =newString[]{ NotesDbAdapter. KEY_TITLE }; int[] to =newint[]{ R.id.text1}; SimpleCursorAdapter notes = new SimpleCursorAdapter (this, R.layout.notes_row , c, from, to ); setListAdapter (notes); }

Paso 6 Vamos a crear el menu para que nos permita aadir nuevas notas a la lista. Necesitamos un botn que al ser pulsado cree una nueva nota: 1. Creamos el texto asociado al botn en res/values/strings.xml

2. Definimos la posicin del botn en el men:


1 publicstaticfinal int INSERT_ID =Menu.FIRST;

3. Aadimos el nuevo botn al men:


1 2 3 4 5 6 @Override publicboolean onCreateOptionsMenu (Menu menu){ boolean result =super.onCreateOptionsMenu (menu); menu.add(0, INSERT_ID, 0, R.string.menu_insert ); return result; }

Paso 7 Una vez creado el men, es necesario atender a las pulsaciones de los elementos del mismo. Aunque en este caso tengamos un nico elemento, hay que tener en cuenta el elemento pulsado:
1 2 3 4 5 6 7 8 9 @Override publicboolean onOptionsItemSelected (MenuItem item){ switch(item.getItemId()){ case INSERT_ID : createNote (); returntrue; } returnsuper .onOptionsItemSelected (item); }

Paso 8 Creamos una nueva nota, la aadimos a la base de datos y actualizamos la lista para reflejar los cambios.
1 2 3 4 5 6 privatevoid createNote (){ String noteName =this.getString(R.string.note_name )+" "+ String.valueOf(mNoteNumber ++); mDbHelper. createNote (noteName, ""); fillData(); }

Paso 9 Ya hemos acabado. Puedes importar el proyecto llamado Notepadv1Solution para comprobar que has hecho todo bien. Maana ms. Cualquier duda en los comentarios! Continuamos con la segunda parte del tutorial para el desarrollo de una aplicacin para Android paso a paso. La primera parte la puedes consultar en utorial Android paso a paso I: Desarrollo de la aplicacin Notepad. En este segundo post, vamos a crear una segunda actividad que nos permita crear y editar notas. Adems, vamos a poder tener la posibilidad de eliminar notas a travs del un men contextual. Objetivos: Crear una nueva actividad. Realizar llamadas a la nueva actividad.

Paso de datos entre las actividades. Crear un nuevo menu contextual. Paso 1 Vamos a crear un men contextual que nos permita eliminar las notas creadas por el usuario. Este men se activar al seleccionar una nota: 1. Relacionamos la lista de notas (ListView) con el menu contextual:
1 registerForContextMenu (getListView ());

2. Creamos el men contextual con la opcin de eliminar una nota:


@Override 1 publicvoid onCreateContextMenu (ContextMenu menu, View v, 2 ContextMenuInfo menuInfo ){ 3 super.onCreateContextMenu (menu, v, menuInfo ); 4 menu.add(0, DELETE_ID, 0, R.string.menu_delete ); 5 }

3. Ahora que tenemos el men creado y relacionado con el listado, tenemos que atender a las pulsaciones en el men contextual:
1 2 3 4 5 6 7 8 9 10 11 12 @Override publicboolean onContextItemSelected (MenuItem item){ switch(item.getItemId ()){ case DELETE_ID: AdapterContextMenuInfo info =(AdapterContextMenuInfo ) item.getMenuInfo (); mDbHelper. deleteNote (info.id); fillData(); returntrue; } returnsuper .onContextItemSelected (item); }

Paso 2 Como hemos visto antes, vamos a dar la posibilidad al usuario de crear y editar notas. Para ello, necesitamos una actividad que controle la interfaz de usuario.
1 2 3 4 5 6 7 8 9 10 11 12 13 publicclass NoteEdit extends Activity { private EditText mTitleText ; private EditText mBodyText ; privateLong mRowId; @Override protected void onCreate(Bundle savedInstanceState ){ super.onCreate(savedInstanceState ); setContentView (R.layout.note_edit ); mTitleText =(EditText) findViewById (R.id.title); mBodyText =(EditText) findViewById (R.id.body); Button confirmButton =(Button) findViewById (R.id.confirm); mRowId =null;

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

Bundle extras = getIntent ().getExtras (); if(extras !=null){ String title = extras.getString (NotesDbAdapter. KEY_TITLE); String body = extras.getString(NotesDbAdapter. KEY_BODY); mRowId = extras.getLong(NotesDbAdapter. KEY_ROWID); if(title !=null){ mTitleText. setText(title); } if(body !=null){ mBodyText. setText(body); } } confirmButton. setOnClickListener (newView.OnClickListener (){ publicvoid onClick(View view){ Bundle bundle =new Bundle(); bundle.putString(NotesDbAdapter. KEY_TITLE , mTitleText. getText().toString()); bundle.putString(NotesDbAdapter. KEY_BODY, mBodyText. getText().toString()); if(mRowId !=null){ bundle.putLong(NotesDbAdapter. KEY_ROWID , mRowId); } Intent mIntent =new Intent(); mIntent.putExtras (bundle); setResult (RESULT_OK, mIntent ); finish(); }}); } }

Paso 3 Ya tenemos la interfaz de usuario, y la actividad para controlarla. Vamos a abrir la nueva actividad desde el listado, para crear una nueva nota. Modificamos el mtodo createNote() de la siguiente manera:
1 privatevoid createNote (){ Intent i =new Intent(this, NoteEdit. class); 2 3 startActivityForResult (i, ACTIVITY_CREATE ); 4}

Paso 4 Para editar las notas ya creadas, creamos un evento para atender a las pulsaciones de los elementos de las listas. Pasamos los datos de la nota a la nueva actividad.
1 2 3 4 5 6 7 8 @Override protected void onListItemClick (ListView l, View v, int position, long id){ super.onListItemClick (l, v, position, id ); Cursor c = mNotesCursor ; c.moveToPosition (position); Intent i =new Intent(this, NoteEdit. class); i.putExtra(NotesDbAdapter. KEY_ROWID , id);

9 i.putExtra(NotesDbAdapter. KEY_TITLE , c.getString( 10 c.getColumnIndexOrThrow (NotesDbAdapter. KEY_TITLE))); 11 i.putExtra(NotesDbAdapter. KEY_BODY, c.getString ( 12 c.getColumnIndexOrThrow (NotesDbAdapter. KEY_BODY))); 13 startActivityForResult (i, ACTIVITY_EDIT ); }

Paso 5 Los mtodos creados anteriormente createNote() y onListItemClick() nos devuelven datos, por lo que necesitamos un mtodo para manejar la respuesta. onActivityResult() es el mtodo ejecutado cuando una actividad devuelve resultados.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Override protected void onActivityResult (int requestCode, int resultCode, Intent intent ){ super.onActivityResult (requestCode, resultCode, intent ); Bundle extras = intent.getExtras(); switch(requestCode ){ case ACTIVITY_CREATE : String title = extras.getString (NotesDbAdapter. KEY_TITLE); String body = extras.getString(NotesDbAdapter. KEY_BODY); mDbHelper. createNote (title, body ); fillData(); break; case ACTIVITY_EDIT : Long rowId = extras.getLong(NotesDbAdapter. KEY_ROWID); if(rowId !=null){ String editTitle = extras.getString (NotesDbAdapter. KEY_TITLE); String editBody = extras.getString(NotesDbAdapter. KEY_BODY); mDbHelper. updateNote (rowId, editTitle, editBody ); } fillData(); break; }

Paso 6 La nueva actividad que hemos definido anteriormente, hay que aadirla a AndroidManifest.xml. Esto permite al sistema conocer los componentes de la aplicacin. Eclipse include un editor para el manifiesto que facilita la edicin del fichero AndroidManifest.xml. Para aadir una nueva actividad: 1. Abrir el fichero AndroidManifest.xml 2. Seleccionar la pestaa Application. 3. Pulsamos Add en la seccin de Application Nodes. 4. En el cuadro de dilogo, seleccionar Create a new element at the top level, in Application y Activity. Pulsar OK. 5. Seleccionar la nueva actividad creada, y en el campo de texto Name, escribir .NoteEdit. Paso 7

Ya hemos terminado esta segunda entrega del tutorial. Si ejecutamos la aplicacin, editamos una nota y pulsamos el botn atrs, veremos que se produce un error. Veremos como solucionar estos problemas en el siguiente post.
/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/

Objetivos: Conocer los eventos del ciclo de vida de la aplicacin. ecnicas para mantener el estado de la aplicacin. Paso 1 La aplicacin actual contiene algunos problemas. Para solucionarlo, vamos a mover la funcionalidad de edicin de notas a la clase NoteEdit. 1. Eliminar el siguiente cdigo de la clase NoteEdit, que obtiene los datos de la nota a travs del Bundle. Vamos a pasar a utilizar la clase DBHelper para obtener los datos directamente de la base de datos.
1 2 3 4 5 Bundle String String mRowId extras = getIntent().getExtras(); title = extras.getString(NotesDbAdapter. KEY_TITLE ); body = extras.getString (NotesDbAdapter. KEY_BODY); = extras.getLong(NotesDbAdapter. KEY_ROWID );

2. Adems, eliminamos la asignacin de los datos a la interfaz de usuario


1 2 3 4 5 6 if(title !=null){ mTitleText. setText(title); } if(body !=null){ mBodyText. setText(body); }

Paso 2 Conectamos la clase NoteEdit con la base de datos. 1. Creamos un nuevo atributo:
1 private NotesDbAdapter mDbHelper ;

2. Conectamos con la base de datos en el constructor, justo despus de llamar al constructor padre:
1 mDbHelper =new NotesDbAdapter (this); 2 mDbHelper. open();

Paso 3

Pasamos a comprobar el estado de la variable savedInstanceState. Esto sirve para comprobar si tenemos datos guardados en el Bundle, que debemos recuperar (Esto ocurre si la actividad pierde el foco y despus se recupera). 1. Reeplazar el siguiente cdigo:
1 2 3 4 5 mRowId =null; Bundle extras = getIntent().getExtras(); if(extras !=null){ mRowId = extras.getLong(NotesDbAdapter. KEY_ROWID ); }

Por este otro


mRowId= savedInstanceState !=null? 1 savedInstanceState. getLong(NotesDbAdapter. KEY_ROWID):null; 2 if(mRowId ==null){ 3 Bundle extras = getIntent().getExtras(); 4 mRowId= extras !=null? extras.getLong(NotesDbAdapter. KEY_ROWID ):null; 5 }

Paso 4 Necesitamos completar los campos con los datos de la nota. Llamamos al mtodo populateFields() que completaremos ms adelante. Insertarlo justo antes de confirmButton.setOnClickListener():
1 populateFields ();

Paso 5 En esta actividad ya no es necesario devolver ningn tipo de datos, ya que vamos a guardar los datos directamente en esta actividad, por lo que es posible simplificar el mtodo onClick() considerablemente:
1 publicvoid onClick(View view){ 2 setResult(RESULT_OK); finish(); 3 4}

Ms adelante veremos como guardar los datos. Paso 6 Definimos el mtodo populateFields():
1 privatevoid populateFields (){ 2 if(mRowId !=null){ 3 Cursor note = mDbHelper. fetchNote (mRowId); startManagingCursor (note); 4 5 6 mTitleText. setText(note.getString (note.getColumnIndexOrThrow (NotesDbA 7 dapter.KEY_TITLE)));

8 mBodyText. setText(note.getString(note.getColumnIndexOrThrow (NotesDbAd apter.KEY_BODY))); } }

Paso 7 Implementamos los mtodos que gestionan el ciclo de vida de Android. Estos mtodos nos permiten guardar y recuperar el estado de la actividad en caso de que esta se cierre o pase a un segundo plano (al recibir una llamada, por ejemplo): 1. onSaveInstanceState(): es llamada por Android cuando la actividad va a ser cerrada. Esto significa que aqu se debe guardar toda la informacin necesaria para restaurar la actividad en su estado anterior. Podemos pensar que es el mtodo contrario a onCreate(), de hecho el Bundle que construimos en este mtodo, es el que ser pasado al mtodo onCreate().
1 2 3 4 5 @Override protectedvoid onSaveInstanceState (Bundle outState ){ super.onSaveInstanceState (outState); outState.putLong(NotesDbAdapter. KEY_ROWID, mRowId); }

2. onPause(): es llamada cuando la actividad va a terminar (con finish()) o pasar a un segundo plano (con una llamada de telfono).
1 2 3 4 5 @Override protectedvoid onPause(){ super.onPause(); saveState(); }

3. onResume(): es llamada al reactivar la actividad. Completamos los campos:


1 2 3 4 5 @Override protectedvoid onResume(){ super.onResume(); populateFields (); }

Paso 8 Para terminar de completar la clase NoteEdit, ya solo nos queda guardar los datos en la base de datos. Creamos el mtodo saveState():
1 2 3 4 5 6 7 privatevoid saveState (){ String title = mTitleText. getText().toString(); String body = mBodyText. getText().toString(); if(mRowId ==null){ long id = mDbHelper. createNote (title, body ); if(id >0){ mRowId = id;

8 9 10 11 12

} }else{ mDbHelper. updateNote (mRowId, title, body ); } }

Paso 9 Volvemos a la clase Notepadv3. En el mtodo onActivityResult(), tenamos implementado todo lo necesario para recibir los datos de la actividad y guardarla en la base de datos. Como este proceso ya lo realizamos en la clase NoteEdit, solo es necesario que actualizemos la lista con los nuevos datos:
1 2 3 4 5 @Override protectedvoid onActivityResult (int requestCode, int resultCode, Intent intent ){ super.onActivityResult (requestCode, resultCode, intent ); fillData(); }

Paso 10 Finalmente, es esta misma clase, al seleccionar un elemento de la lista, ya no es ncesario pasar todos los datos de la nota, nicamente el id, por lo que el mtodo onListItemClick(), quedara de la siguiete manera:
1 2 3 4 5 6 7 @Override protectedvoid onListItemClick (ListView l, View v, int position, long id){ super.onListItemClick (l, v, position, id ); Intent i =new Intent(this, NoteEdit. class); i.putExtra(NotesDbAdapter. KEY_ROWID, id); startActivityForResult (i, ACTIVITY_EDIT ); }

Y con este ltimo post hemos terminado el tutorial. Espero que os haya servido de ayuda y, como siempre, cualquier duda o pregunta en los comentarios.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[ tulo original: Tutorial: Notepad Exercise 1] Documento original: utorial: Notepad Exercise 1 En este ejercicio construiremos una simple lista de anotaciones que permitir al usuario agregar una nueva nota, pero por ahora no le permitir editarla. Este ejercicio demostrar:
y Conceptos bsicos de una "ListActivity". Adems, la creacin y manipulacin de opciones de un men.

y Recuperacin y almacenamiento de las notas en una base de datos "SQLite". y Cmo enlazar datos dentro de una "ListView" usando un "ArrayAdapter" (una de las forms ms simples de enlazar datos a un "ListView"). y Los conceptos bsicos de diseo de una pantalla, incluyendo cmo disear una lista, cmo agregar elementos al men de una "Activity" y cmo manipular la seleccin de esos elementos.

Paso #1
[ tulo original: Step 1] Importar el proyecto "Notepadv1" a nuestro "workspace" de Eclipse. NO A: "Notepadv1" es un proyecto que provee el punto de partida a este ejercicio y nos ahorrar el tiempo de hacer las cosas que ya aprendiste al desarrollar la aplicacin "Hola Mundo". A continuacin estn las instrucciones para esta seccin:
y Dentro del "Package Explorer" haz clic con el botn derecho y selecciona "Import... > General > Existing Projects into Workspace. Luego presiona el botn "Next > ". y A continuacin, presiona el botn "Browse" y navega hasta donde extrajiste los directorios de los ejercicios y selecciona "Notepadv1". Finalmente, presiona el botn "OK". y Despus del paso anterior deberas ver el elemento "Notepadv1" en la lista de proyectos con una marca de seleccionado al lado de l. y Presiona el botn "Finish". y El proyecto debera haberse abierto en el "Package Explorer" y estar listo para trabajar con l. y Si vieras un error relacionado con el archivo "AndroidManifest.xml", o con un archivo ".zip" de Android, has clic con el botn derecho sobre el proyecto y selecciona desde el men de contexto "Android ools > Fix Project Properties".

Paso #2
[ tulo original: Step 2] Dale un vistazo a la clase "DBHelper". Esta clase encapsula el acceso y actualizacin de los datos de nuestras anotaciones almacenadas en una base de datos "SQLite" local en nuestro dispositivo.

Normalmente, el acceso a datos debera ser implementado usando un "ContentProvider", y de hecho la aplicacin "Notepad" que est incluida en el SDK (en el directorio "samples/") implamenta un "ContentProvider". Sin embargo, no hay ninguna restriccin en utilizar directamente tu propia base de datos tal como lo haremos en este ejercicio. Lo ms importante a destacar de la clase "DBHelper" es que toma la responsabilidad de todos los detalles relacionados con el almacenamiento, recuperacin y actualizacin de datos de una base de datos "SQLite". Provee mtodos para: (A) recuperar todas los registros, (B) recuperar un registro basado en un "rowIds", (C) crear un nuevo registro, (D) borrar un registro (E) actualizar un registro.
Accesando y modificando datos

[ tulo original: Accessing and modifying data] En este ejercicio, vamos a usar directamente una base de datos SQLite para almacenar nuestros datos, pero en una aplicacin real sera mucho ms conveniente escribir un "ContentProvider" para encapsular este comportamiento. Si t ests interesado en aprender ms sobre "ContentProvider" o el tema "Almacenamiento, recuperacin y exposicin de datos".

Paso #3
[ tulo original: Step 3] Abre el archivo "notepad_list.xml" que est localizado en "res/layout" y dale un vistazo. Este archivo contiene la definicin del diseo de la pantalla y contiene el punto de inicio para dibujar la pantalla.
y

odos los archivos de diseo de pantalla comienzan con un encabezado XML.

y Con frecuencia, pero no siempre, la raz del documento de diseo es una definicin del tipo de distribucin que tendrn los elementos en la pantalla, en este caso es"LinearLayout". y El "xml namespace" de Android (xmlns:android="http://schemas.android.com/apk/res/android") debera ser siempre definido como un atributo del elemento de mayor jerarqua en el documento de diseo de pantalla, de esa forma el espacio de nombre "android:" podr ser utilizado por los elementos que estn anidados.
Esquemas y actividades

[ tulo original: Layouts and activities] Muchas actividades tendrn un esquema asociado a ellas. El esquema ser la "cara" que el usuario ver de la actividad. En este ejemplo, el esquema ocupar completamente la pantalla y proveer una lista de anotaciones.

Los esquema de pantalla completa no son la nica opcin para una actividad. tambin podras usar un esquema flotante (por ejemplo para un mensaje de alerta) o quiz ni siquiera necesites un esquema (en este caso la actividad es invisible al usuario a menos que quieras asociar un esquema a la actividad).

Paso #4
[ tulo original: Step 5] Ahora, necesitamos modificar el diseo de la pantalla para que contenga nuestra lista. Para hacer esto agregaremos dentro de la etiqueta "LinearLayout" las etiquetas "ListView" y " extView". El siguiente archivo corresponde a la nueva versin despus de realizar las modificaciones:
<?xml version="1.0" encoding="utf -8"?> <LinearLayout xmlns:android="http://schemas.android.co m/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ListView id="@+id/android:list" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView id="@+id/android:empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/no_notes"/> </LinearLayout>

y Los elementos "ListView" y " extView" pueden ser entendidos como dos vistas alternativas, es decir, en cualquier momento slo una de ellas ser desplegada. El elemento "ListView" ser usado slo cuando tengamos anotaciones para ser mostradas y " extView" ser usado para desplegar el mensaje "No Notes Yet!" cuando an no tengamos anotaciones para mostrar. (El valor inicial de " extView" est definido como un recurso de tipo "string"). y El caracter "@" en los atributos "id" de "ListView" y " extView" le indican al "XML parser" que debe reemplazar estos valores por valores definidos en el archivo de recursos o en la "Android platform". y Los textos "android:list" y "android:empty" son identificadores que son proporcionados por la "Android platform". El elemento identificado con "empty" ser usado automticamente cuando no hayan datos para ser desplegados en la lista.

En general, la clase "android.R" es un conjunto predefinido de recursos que la plataforma te provee, por el contrario, la clase "R" de tu proyecto es el conjunto de recursos que tu proyecto a definido. Los recursos que se encuentran definidos en la clase "android.R" pueden ser usados en los archivos XML anteponiendo el espacio de nombre "android:", como se ve en el ejemplo anterior.

Paso #5
[ tulo original: Step 5] Para crear una vista con una lista, tambin debemos definir la vista para cada una de las filas:
y Crearemos un nuevo archivo dentro de "res/layout" llamado "notes_row.xml". y Agregarenos el siguiente contenido al archivo:
<?xml version="1.0" encoding="utf -8"?> <TextView id="@+id/text1" xmlns:android="http://schemas.androi d.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"/>

y Esta es la vista que ser usada para el ttulo de cada anotacin. Es slo un texto. y En este caso, hemos creado un nuevo identificador llamado "text1". El caracter "+" que est a continuacin del caracter "@" indica que el identificador deber ser creado automticamente si es que no existe, es decir, estamos definiendo "text1" dinmicamente y luego emplendolo. y Despus de grabar el archivo, si abrimos el archivo "R.java" deberemos ver una nueva definicin para "notes_row" y "text1", lo que significa que ahora tendremos acceso a esos elementos desde nuestro cdigo.
Recursos y la clase "R"

[ tulo original: Resources and the R class] En los proyectos Eclipse, los subdirectorios de "res/" son especiales. Hay un estructura especfica para los directorios y archivos bajo este directorio. En particular, los recursos definidos en estos directorios y archivos tendrn sus correspondientes entradas en la clase "R" lo que permitir que sea muy fcil referenciarlos y usarlos desde tus aplicaciones. Adicionalmente, estos archivos sern empaquetados y distribuidos como parte de tu aplicacin.

Paso #6
[ tulo original: Step 6] A continuacin, abre la clase "Notepadv1"; ya que la vamos a modificar para convertirla en el adaptador de nuestra lista y as desplegar las anotaciones y agregar nuevas. La clase "Notepadv1" es una subclase de "Activity" llamada "ListActivity", la cual tiene un funcionalidad adicional que es proporcionar todo tipo de operaciones que

comnmente desearamos realizar con una lista. Por ejemplo, desplegar un nmero arbitrario de filas en la lista y permitir seleccionarlas. Dale un vistazo al cdigo de la clase "Notepadv1". Hay algunas definiciones de constantes, seguidas de propiedades privadas y finalmente algunos mtodos que sobreescriben mtodos de la super clase.

Paso #7
[ tulo original: Step 7] Cambia la herencia de "Notepadv1" de "Activity" a "ListActivity":
public class Notepadv1 extends ListActivity

NO A: Debes importar la clase "ListActivity" en el archivo "Notepadv1". En Eclipse puedes precionar ctrl shift O (Windows y Linux).

Paso #8
[ tulo original: Step 8] Debemos agregar cdigo a los siguientes mtodos: "onCreate", "onCreateOptionsMenu" y "onOptionsItemSelected".
yonCreate() es llamado cuando la "Activity" es activada. Es una especie de mtodo "main" en una aplicacin "C". Este mtodo es utilizado para definir recursos y estados de la "Activity" que se est ejecutndo. yonCreateOptionsMenu() es usado para poblar el men de la "Activity". Este men es mostrado cuando el usuario presiona el botn de men. yonOptionsItemSelected() es usado para controlar los eventos generados por el men. Por ejemplo, cuando el usuario selecciona un elemento del men.

Paso #9
[ tulo original: Step 9] A continuacin modificaremos el mtodo "onCreate()". Aqu definiremos el ttulo de la actividad (el ttulo es mostrado en el borde superior de la pantalla). Usaremos el diseo indicado en "notepad_list.xml" para desplegar los contenidos de la actividad. Adems, definiremos una instancia de "DBHelper" para tener acceso de los datos de las anotaciones.
y Llamamos al mtodo "super.onCreate()" con el parmetro "icicle" que entrega nuestro mtodo.

y Llamamos al mtodo "setContentView()" para definir "R.layout.notepad_list" como el esquema que usaremos. y Creamos una propiedad privada llamada "dbHelper", la cual es una instancia de la clase "DBHelper" (esto lo hacemos antes del cdigo del mtodo "onCreate()"). y En el mtodo "onCreate()", instanciamos la propiedad "dbHelper" (debemos pasar el valor "this" como argumentos del constructor de la clase "DBHelper"). y Finalmente, llamamos al mtodo "fillData()" (ser definido ms adelante) para llenar nuestra lista con datos. y l mtodo "onCreate()" debera verse as:
/** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.notepad_list); dbHelper = new DBHelper(this); fillData(); }

Recuerda agregar la definicin de la propiedad (justo debajo de la definicin de "private int noteNumber = 1;"):
private DBHelper dbHelper;

Paso #10
[ tulo original: Step 10] A continuacin modificaremos el mtodo "onCreateOptionsMenu()". Por ahora slo agregaremos una opcin al men de la aplicacin: "Add Item". El texto para esta opcin es parte de los recursos de la aplicacin y est definido en "strings.xml".
y En el archivo "strings.xml" (localizado en "res/values"), agrega una nueva etiqueta para "menu_insert" con el texto "Add Item".
<string name="menu_insert">Add Item</string>

y Necesitamos agregar una constante para la posicin del men: public static final int INSER _ID = Menu.FIRST; y En el mtodo "onCreateOptionsMenu()" agregar el tem del men. Tambin nos hacemos cargo del resultado retornado por el llamado del mtodo "super.onCreateOptionsMenu(menu)".

La nueva versin del mtodo debe verse de la siguiente forma:

@Override public boolean onCreateOptionsMenu(Menu menu) { boolean result = super.onCreateOptionsMenu(menu); menu.add(0, INSERT_ID, R.string.menu_insert); return result; }

Ms informacin sobre mens

[Ttulo original: More on menus] La aplicacin "Notepad" que estamos construyendo slo muestra la superficie de los mens. Podemos usar teclas para acelarar el uso de mens, crear submens e incluso agregrar items de mens a otras aplicaciones.

Paso #11
[Ttulo original: Step 11] Este mtodo va a responder cuando se seleccione en el men la opcin "Add Note". Cuando la opcin sea seleccionada, este mtodo ser llamado con el valor de "item.getId()" en "INSERT_ID" (la constante que nosotros definimos para identificar este elemento del men). Realizaremos las siguientes acciones:
y El llamado al mtodo "super.onOptionsItemSelected(item)" va al final del mtodo porque primero nos interesa capturar los eventos. y Codificamos una sentencia "switch" para evaluar "item.getId()". y El "case INSERT_ID:" llama al mtodo "createNote()". y Retornamos el valor devuelto por "super.onOptionsItemSelected(item)".

La nueva versin del mtodo debe verse de la siguiente forma:


@Override public boolean onOptionsItemSelected(Item item) { switch (item.getId()) { case INSERT_ID: createNote(); fillData(); break; } return super.onOptionsItemSelected(it em); }

Paso #12
[Ttulo original: Step 12] Creacin del mtodo "createNote()". En esta primera versin de "createNote()" simplemente crearemos una nueva nota con un ttulo basado en un contador: "Note 1", "Note 2"... y tendr un cuerpo en blanco. Algunas observaciones sobre el cdigo:
y La sentencia: String noteName = "Note " + noteNumber++; es usada para construir el ttulo de la nota. y El llamado a "dbHelper.createRow()" crear la nota usando "noteName" como ttulo y la el texto vaco ("") como cuerpo.

La nueva versin del mtodo debe verse de la siguiente forma:


private void createNote() { String noteName = "Note " + noteNumber++; dbHelper.createRow(noteName, ""); fillData(); }

Paso #13
[Ttulo original: Step 13] Creacin del mtodo "fillData()". Este mtodo usa un "ArrayAdapter", el cual es la forma ms fcil de poner datos en un "ListView". Un "ArrayAdapter" toma una "List" o un arreglo de "String" y los enlaza a una vista de texto provista en el diseo de una fila de la lista (esto es el campo "text1" de nuestro archivo "notes_row.xml"). Este mtodo simplemente obtiene una lista de anotaciones desde el "database helper" y construye una "List" de "String" usando el ttulo de cada registro y entonces crea un "ArrayAdapter" con todos esos tems y los asocia con el diseo "notes_row". Algunas observaciones sobre el ccdigo:
y "ArrayAdapter" necesita un "List" conteniendo los tems a desplegar. y Los datos son recuperados como registros, y el ttulo del registro es utilizado para poblar la lista. y Nosotros indicamos que "notes_row" es la vista que usaremos como receptora de los datos. y Para importar automticamente las clases utilizadas presiona ctrl shift O.

La nueva versin del mtodo debe verse de la siguiente forma:


private void fillData() { // We need a list of strings for the list items List<String> items = new ArrayList<String>(); // Get all of the rows from the database and create the item list List<Row> rows = dbHelper.fetchAllRows(); for (Row row : rows) { items.add(row.title ); } // Now create an array adapter and set it to display using our row ArrayAdapter<String> notes = new ArrayAdapter<String>(this, R.layout.notes_row, items); setListAdapter(notes); return; }

NOTA: En este ejercicio hemos utilizado "ArrayAdapter", pero este objeto no es una solucin escalable. Generalmente, "SimpleCursorAdapter" podra ser empleado en combinacin con "ContentProvider" o al menos un "Cursor" retornado desde el "query".
Adaptadores de listas

[Ttulo original: List adapters] Nuestro ejemplo utiliza un adaptador de coleccin muy simple, el cual asocia una coleccin o lista de items con una "ListView". En Android es ms comn que los adaptadores de listas vayan mano a mano con "ContentProviders" y esta es una forma muy fcil de usar listas. Para asociar un "ContentProvider" con una "ListView" podemos usar un "SimpleCursorAdapter" que asociar los datos desde un "ContentProvider" con una "ListView".

Paso #14
[Ttulo original: Step 14] Ejecucin de la aplicacin.
y Paso #14

http://2.bp.blogspot.com/__WZr8mbWg3o/R17iAnUfWNI/AAAAAAAAAB0/qKkKGa88g1Q/s32 0/figura-07.jpg

Solucin y prximos pasos


[Ttulo original: Solution and Next Steps] Puedes ver la solucin a este clase en "Notepadv1Solution" para comparar su contenido con el tuyo.
/////////////////////////////////////////////////////////////

Este ejercicio demostrar:


y y y y

Desarrollo de una nueva "Activity" y cmo agregarla al archivo "Android manifest". Invocacin asincrnica de otra "Activity" usando "startSubActivity()". Paso de datos entre "Activity" ("bundles"). Cmo utilizar caractersticas ms avanzadas de diseo de pantalla.

Paso #1 Importa el proyecto "Notepadv2" de la misma forma en que lo describ en el tutoral anterior. Los archivos de este proyecto estn localizados en el directorio "NotepadCodeLab". Si se te presenta un error con el archivo "AndroidManifest.xml" o con el archivo "android.zip", abre el men de contexto del proyecto y selecciona la opcin "Android Tools->Fix Project Properties". Expande el proyecto "Notepadv2" y dale un vistazo general:
y

y y y

Abre y examina el archivo "strings.xml" (directorio "res/values"). Vers la declaracin de nuevas cadenas de texto, las cuales las usaremos en las nuevas funcionalidades. Abre y examina el encabezado de la clase "Notepadv2". Notars que tambin hay algunos cambios: declaraciones de nuevas constantes y propiedades. Tambin notars que el mtodo "fillData()" ha sido modificado para usar la propiedad "rows" en vez de una variable local. Adicionalmente, hemos sobreescrito nuevos mtodos: "onListItemClick()" y "onActivityResult()".

Paso #2 Revisa el mtodo "onCreate()", vers que no ha cambiado desde la versin anterior.

Paso #3 Debemos agregar la opcin "Delete Note" al men de la "Activity". Para esto:
y

En el mtodo "onCreateOptionsMenu()" agrega la siguiente lnea:

menu.add( 0, DELETE_ID, R.string.menu_delete);

Ahora, el mtodo debera verse as:

@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add( 0, INSERT_ID, R.string.menu_insert); menu.add( 0, DELETE_ID, R.string.menu_delete); return true ; }

Paso 4
y

En el mtodo "onMenuItemSelected()" agrega el siguiente fragmento de cdigo:

case DELETE_ID: dbHelper.deleteRow(rows.get(getSelection()).rowId); fillData(); break;

Este cdigo usa el mtodo "getSelection()" perteneciente a "ListActivity", el cual nos indica cual es el actual elemento seleccionado de la lista. Luego, referenciamos el registro de esa anotacin y finalmente tomamos el valor de la propiedad "rowId". Es este valor el que finalmente utilizamos con "deleteRow" para borrar el registro.
y y

Posteriormente, llamamos al mtodo "fillData()" para mantener todo actualizado. El mtodo debera quedar de la siguiente forma:

@Override public boolean onMenuItemSelected( int featureId, Item item) { super.onMenuItemSelected(featureId, item); switch(item.getId()) { case INSERT_ID: createNote(); fillData(); break; case DELETE_ID: dbHelper.deleteRow(rows.get(getSelection()).rowId); fillData(); break; }

return true ; }

Paso 5 Ahora, modificaremos el cuerpo del mtodo "createNote()":


y

Definiremos un "Intent" para crear una anotacin ("ACTIVITY_CREATE"). Los argumentos que utilizaremos ser "this" y la clase "NoteEdit". A continuacin, gatillaremos el "Intent" usando el mtodo "startSubActivity()".

NOTA: La clase "NoteEdit" ser definida en unos momentos. NOTA: En este ejemplo, nuestro "Intent" utiliza el nombre especfico de una clase. Mientras esto es adecuado para determinadas circunstancias, lo ms comn es invocar un "Intent" usando una "Action" y una "URI". Ver "android.content.Intent" para ms informacin. Paso 6 Modificaremos el cuerpo del mtodo "onListItemClick()". El mtodo "onListItemClick()" sobreescribe el mtodo que es llamado cuando un usuario selecciona un elemento de la lista. Este mtodo entrega 4 parmetros:
y y y y

Objeto ListView : referencia al objeto desde el cual fue invocado el elemento. Objeto View : referencia al objeto que fue seleccionado dentro de la ListView. Un entero con la posicin del elemento seleccionado. Un entero con la identificacin del elemento que fue seleccionado.

En nuestro ejemplo, podemos ignorar los dos primeros parmetros (tenemos slo una "ListView" desde la cual el elemento pudo ser seleccionado). Tambin ignoraremos la identificacin del elemento. Todo lo que nos interesa por ahora es la posicin del elemento que el usuario seleccion. Utilizaremos esta posicin para recuperar los datos de la anotacin desde la lista y los empaquetamos para enviarlo a la "Activity" "NoteEdit". Este mtodo crea el "Intent" para editar la anotacin usando la clase "NoteEdit". Luego, agregamos todos los datos al "Intent" (ttulo, cuerpo de la anotacin y la identificacin). Finalmente, gatillamos el "Intent" invocando al mtodo "startSubActivity()" con los argumentos "ACTIVITY_EDIT" y la clase "NoteEdit".
super.onListItemClick(l, v, position, id); Intent i = new Intent(this, NoteEdit. class); i.putExtra(KEY_ROW_ID, rows.get(position).rowId); i.putExtra(KEY_BODY, rows.get(position).body); i.putExtra(KEY_TITLE, rows.get(position).title); startSubActivity(i, ACTIVITY_EDIT);

El mtodo "putExtra()" permite agregar elementos adicionales al paquete del "Intent". Paso 7

A continuacin modificaremos el mtodo "onActivityResult()". El mtodo "onActivityResult()" sobreescribe un mtodo que es invocado cuando una sub "Activity" finaliza su tarea. Los parmetros que este mtodo entrega son:
y y

requestCode : s el cdigo original utilizado en la invocacin del "Intent" (en nuestro caso podr ser "ACTIVITY_CREATE" o "ACTIVITY_EDIT"). resultCode : es el resultado (o cdigo de error) del llamado. Este valor debera ser cero si todo fue correcto y valor distinto para indicar que algo fall. Existen algunos cdigos predefinidos que pueden ser utilzados, pero tambin pueden definirse nuevos cdigos para errores ms especficos. data : esta es una cadena de texto que es utilizada para recibir algn tipo de informacin descriptiva (por ejemplo: el texto que el usuario escribi en un cuadro de dilogo). Esto es til nicamente cuando tenemos slo una cosa que devolver. Si requerimos retornar ms informacin, debemos usar "extras". extras : este parmetro entrega los "extras bundle" (si es que existen) que retorn el "Intent" invocado.

La combinacin de "startSubActivity()" y "onActivityResult()" puede ser vista como un llamado asincrnico a un procedimiento remoto ("asynchronous RPC" o "remote procedure call"). Esta es la forma recomendada para que una "Activity" invoque a otra "Activity" y compartir servicios. A continuacin est el cdigo completo de este mtodo:

@Override protected void onActivityResult( int requestCode, int resultCode, String data, Bundle extras) { super.onActivityResult(requestCode, resultCode, data, extras); switch(requestCode) { case ACTIVITY_CREATE: String title = extras.getString(KEY_TITLE); String body = extras.getString(KEY_BODY); dbHelper.createRow(title, body); fillData(); break; case ACTIVITY_EDIT: Long rowId = extras.getLong(KEY_ROW_ID); if (rowId != null) { String edi tTitle = extras.getString(KEY_TITLE); String editBody = extras.getString(KEY_BODY); dbHelper.updateRow(rowId, editTitle, editBody); } fillData(); break; } return; }

y y y y

En este mtodo distinguimos los resultados de dos "Activity": "ACTIVITY_CREATE" y "ACTIVITY_EDIT". En el caso de "ACTIVITY_CREATE", tomamos el ttulo y el cuerpo desde "extras" para usarlos en la creacin de la anotacin. En el caso de "ACTIVITY_EDIT", tomamos adems el "KEY_ROW_ID" para localizar el registro que deseamos actualizar. El mtodo "fillData()" al final nos asegura que todo ser actualizado.

Paso 8 Abre el archivo "note_edit.xml" y revsalo. Este archivo contiene la definicin de la pantalla que ser usada para editar nuestras anotaciones. Este archivo hace uso de un nuevo parmetro: "android:layout_weight" (en este caso tiene el valor "1"). layout_weight es usado en "LinearLayouts" para asignar a las vistas un nivel de "importancia" dentro del diseo de la pantalla. Todas las vistas tienen un valor por omisin de cero para "layout_weight", lo cual significa que ellas pueden ocupar el espacio que requieran para ser desplegadas. Al asignar un valor mayor que cero har que el resto del espacio disponible sea dividido entre el padre de acuerdo al valor de "layout_weight" y su proporcin con el total de "layout_weight", especificado en el actual trazado y en otras vistas. Para dar un ejemplo de lo anterior, digamos que tenemos una etiqueta de texto y dos reas de edicin en un vista horizontal. La etiqueta de texto no tiene especificado valor para su "layout_weight", por lo tanto tomar el mnimo espacio requerido para desplegarse. Si el valor de "layout_weight" para las reas de texto es "1", el restanto espacio dentro del rea definida por el padre ser dividida entre ambas. Si la primera rea tuviera un valor de "1" y la segunda un valor de "2" para "layout_weight", entonces un tercio del espacio disponible ser entregado a la primera rea y los dos restantes a la segunda. Este diseo de pantalla tambin demuestra cmo anidar mltiples esquemas para as lograr complejos trazados de pantalla. En este caso, el esquema horizontal lineal est anidado dentro de uno vertical, lo cual permite que la etiqueta del ttulo y el rea de edicin estn una al lado de otra. Paso 9 Crea una clase llamada "NoteEdit" y que extienda "android.app.Activity". Esta es la primera vez que crearemos una "Activity" sin la ayuda del "Android Eclipse plugin". Al hacerlo de esta manera, el mtodo "onCreate()" no es automticamente etiquetado con la anotacin de sobreescritura. Es difcil imaginar una "Activity" que no sobreescriva el mtodo "onCreate()". A continuacin estn las instrucciones en detalle:

1. Abre el men de contexto del paquete "com.google.android.demo.notepad2" y selecciona "New->Class". 2. Escribe en el campo "Name:" el nombre de la clase ("NoteEdit"). 3. En el campo "Superclass:", escribe "android.app.Activity" o puedes simplemente escribir "Activity" y presionar "Ctrl-Space" (Windows y Linux) para invocar el asistente de cdigo y encontrar path completo del paquete en el cual est esta clase. 4. Presiona el botn "Finish". 5. En el editor de texto abre el men de contexto y selecciona la opcin "Source", luego selecciona "Override/Implement Methods...". 6. Busca el mtodo "onCreate(Bundle)" y seleccinalo. 7. Presiona el botn "OK". Paso 10 Completaremos el cdigo del mtodo "onCreate()". Haremos las declaraciones necesarias para definir el ttulo de nuestra "Activity" ("Edit Note"). Este valor est definido en el archivo "strings.xml". Aqu tambin definiremos que la vista que utilizaremos ser aquella definida en el archivo "note_edit.xml layout". Despus de esto, podemos asociar a objetos Java las vistas correspondientes al ttulo, el cuerpo de la anotacin y el botn de confirmacin. De esta forma, nuestro cdigo puede usarlos para asignar y recuperar el texto del ttulo y el cuerpo; y adems asociar codigo al evento gatillado cuando el usuario presiona el botn de confirmacin. Los valores que fueron enviados por la "Notepadv2" sern extraidos desde el paquete y usados para llenar el ttulo y el cuerpo de la anotacin. La identificacin de la anotacin la almacenaremos para saber que registro estamos editando.
y

Asociacin de la "Activity" con un esquema:

setContentView(R.layout.note_edit); y

Examinar el esquema de pantalla para encontrar el ttulo, el cuerpo y el botn de confirmaci. Utilizamos los identificadores generados en la clase "R" y luego los convertimos al tipo apropiado.

titleText = (EditText) findViewById(R.id.title); bodyText = (EditText) fi ndViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm);

NOTA: "titleText" y "bodyText" son propiedades de la clase que an no hemos definido.


y

Declarar una propiedad llamada "rowId", la cual almacenar la identificacin del registro editado.

private Long rowId; y

Agregar cdigo para inicializar el ttulo, cuerpo y la propiedad "rowId" a partir de los datos extraidos del paquete recibido desde "Notepadv2".

rowId = null; Bundle extras = getIntent().getExtras(); if (extras != null) { String title = extras.getString(Notepadv2.KEY_TITLE); String body = extras.getString(Notepadv2.KEY_BODY); rowId = extras.getLong(Notepadv2.KEY_ROW_ID); if (title != null) { titleText.setText(title); } if (body != null) { bodyText.setText(body); } } y

Definir un controlador para el evento clic del botn de confirmacin. Esto lo hacemos utilizando el mtodo "onClickListener()".

NOTA: Los controladores de eventos ("listeners") son uno de los aspectos ms difciles de entender en la implementacin de una "UI", pero lo que intentamos hacer aqu es bastante simple. Lo que deseamos hacer es simplemente llamar al mtodo "onClick()" cuando el usuario presione el botn de confirmacin. Dentro de este mtodo podremos hacer los necesario para devolver los valores ingresados por el usuario al "Intent" que llamo a esta "Activity". La tcnica empleada en este cdigo se llama "anonymous inner class". Resulta enredado de leer a menos que hayas visto este patrn anteriormente, pero por ahora slo nos interesa usar este cdigo a modo de receta de cmo invocar un mtodo como reaccin a un evento de la "UI". Paso 11 Completaremos el cuerpo del mtodo "onClick()". Este es el cdigo que se ejecutar cuando el usuario haga clic sobre el botn de confirmacin. Aqu es donde debemos recuperar el ttulo y cuerpo de la anotacin y colocarlos dentro del paquete de datos que devolveremos a la "Activity" que invoc esta "Activity". Si la operacin es editar en vez de crear, tambin deberemos poner la identificacin del registro de la anotacin.
y

Creacin del paquete donde pondremos el ttulo y cuerpo de la anotacin.

Bundle bundle = new Bundle(); bundle.putString(Notepadv2.KEY_TITLE, titleText.getText().toString()); bundle.putString(Notepadv2.KEY_BODY, bodyText.getText().toString() ); if (rowId != null) { bundle.putLong(Notepadv2.KEY_ROW_ID, rowId); } y

Asignar la informacin de resultado, incluyendo el paquete y resultado final de la operacin.

setResult(RESULT_OK, null, bundle); finish();

El mtodo "setResult()" es usado para asignar el cdigo de retorno, la cadena de informacin textual y el paqueta de datos que ser entregado al "Intent" que invoc a esta "Activity". En este caso suponemos que todo estar bien, asi es que devolvemos "RESULT_OK" como valor del cdigo de retorno. No usaremos la cadena de informacin textual , por esta razn estamos pasando el valor "null". El mtodo "finish()" es usado como una seal que la "Activity" ha realizado su tarea (una especia de "return"). Todos los argumentos entregados a "setResul()" van a ser devueltos junto con el control de ejecucin.
y

La siguiente es la declaracin de las propiedades utilizadas en el cdigo de esta clase.

private EditText titleText; private EditText bodyText; private Long rowI d; y

El cdigo completo del mtodo "onCreate()" es mostrado a continuacin.

@Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.note_edit); titleText = (EditText) findViewById(R.id.title); bodyText = (EditText) findViewById(R.id.body); Button confirmButton = (Button) findViewById(R.id.confirm); rowId = null; Bundle extras = getIntent().getExtras(); if (extras != null) { String title = extras.getString(Notepadv2.KEY_TITLE); String body = extras.getString(Notepa dv2.KEY_BODY); rowId = extras.getLong(Notepadv2.KEY_ROW_ID); if (title != null) { titleText.setText(title); } if (body != null) { bodyText.setText(body); } } confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Bundle bundle = new Bundle(); bundle.putString(Notepadv2.KEY_TITLE, titleText.getText().toString()); bundle.putString(Notepadv2.KEY_BODY, bodyText.getText().toString()); if (rowId != null) { bundle.putLong(Notepadv2.KEY_ROW_ID, rowId);

} setResult(RESULT _OK, null, bundle); finish(); } }); } Paso 12 Finalmente, la nueva "Activity" debe ser declarada en el archivo "Android Manifest". Antes de que una actividad pueda ser "vista" por Android, esta actividad debe tener su propia entrada en el archivo"AndroidManifest.xml". Esto le entregar al sistema la informacin necesaria para localizar la actividad y saber que requiere para funcionar. A continuacin se muestra el archivo "AndroidManifest.xml" modificado:
<?xml version="1.0" encoding="utf -8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.demo.notepad2"> <application android:icon="@drawable/icon"> <activity class=".Notepadv2" android:label="@string/app_name"> <intent-filter> <action android:value="android.intent.action.MAIN" /> <category android:value="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity class=".NoteEdit"/> </application> </manifest>

Paso 13 Ejecucin de la aplicacin. 1. Haz clic con el botn derecho sobre el proyecto "Notepadv2" para abrir el men de contexto y seleccionar "Run As > Android Application ".

/**/*/*/*/*/*/*/++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++

Desarrollo de aplicaciones mixtas (web/nativa) en Android.


Introduccin
En ocasiones crear una aplicacin basada en una arquitectura mixta entre una aplicacin nativa y una aplicacin web y comunicarlas en base a nuestras necesidades puede ser muy adecuado y ahorrarnos mucho tiempo de desarrollo.

Todos estaremos deacuerdo en que:


1. Una aplicacin web (html, javascript, css, etc) tiene la ventaja de que no hay que distribuir la aplicacin cuando hay un cambio en la misma, con cambiar el cdigo en el servidor bastara. 2. Una aplicacin web no puede acceder directamente a los recursos del dispositivo: GPS, camara de fotos, agenda, etc.

Y digo yo, por qu no una mezcla que aproveche ambas ventajas?.. pues bien, de eso se trata este pequeo tutorial.. ver como comunicarnos entre ambas partes web y nativa Si quieres trastear, puedes descargarte el cdigo fuente desde clic aqu. Si quieres probarlo directamente en tu dispositivo puedes descargarte la aplicacin desde clic aqu

Construccin de una aplicacin mixta en Android


El cdigo fuente est autocomentado, no creo que tengas problemas si tienes una base de programacin en Android.
Captura de pantalla de la aplicacin a construir:

assert/carlos -garcia.html

nica pgina web que compone la aplicacin, aunque podra haber sido generada dinmicamente en un servidor, en este ejemplo est ubicada como un esttico en la carpeta assert del proyecto.
view plainprint? 1. <html> 2. <head> 3. <title>Android WebView y NativeApp</title> 4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5. <script language="javascript"> 6. function callFromAndroidToJS(texto) { 7. document.getElementById("target").innerHTML=texto; 8. } 9. function callFromJSToAndroid() { 10. jsNativeInterface.metodoDemo1(); 11. } 12. function callFromJSToAndroidForReadJson() { 13. var datosJson = eval('(' + jsNativeInterface.metodoDemo2() + ')'); 14. document.getElementById("target").innerHTML=datosJson.timestamp; 15. } 16. </script> 17. <style type="text/css"> 18. a { color: green; text-decoration: underline;} 19. </style> 20. </head> 21. <body> 22. <h1>carlos-garcia.es</h1> 23. <ul> 24. <li><p>Prueba 1: <a onclick="callFromJSToAndroid();">Haga clic aqu</a> para i nvocar desde el JavaScript a la aplicacin Android</p></li> 25. <li><p>Prueba 2: <a onclick="callFromJSToAndroidForReadJson();">Haga clic aq u</a> para invocar desde el JavaScript a la aplicacin Android y leer JSON</p></li> 26. <li><p>Prueba 3: <span id="target">Este texto ser sustituido desde la aplicaci n nativa</span></p></li> 27. </ul> 28. </body> 29. </html>

Ten mucha precaucin con la parte de javascript, pues si tienes un error como por ejemplo poner "var" en los parmetros de los mtodos no ves errores en los los, simplemente NO funciona la comunicacin.
res/layout/main.xml

Interface grfico de la aplicacin, observe que abajo hay un WebView que ser donde se muestre la parte web.
view plainprint?

1. <?xml version="1.0" encoding="UTF-8"?> 2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3. android:orientation="vertical" android:layout_width="fill_parent" android:layout_h eight="fill_parent"> 4. 5. <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> 6. <EditText android:id="@+id/txt1" android:hint="Escribe algo y acepta" android:lay out_width="wrap_content" android:layout_height="wrap_content"/> 7. <Button android:id="@+id/btn1" android:text="Aceptar" android:layout _width="wrap_content" android:layout_height="wrap_content"/> 8. </LinearLayout> 9. 10. <WebView android:id="@+id/webview" android:layout_width="fill_parent" android :layout_height="fill_parent"/> 11. </LinearLayout>
es.carlosgarcia.android.MyAndroidToJsInterface

Interface de comunicacin entre la parte web y la parte no web (nativa).


view plainprint? 1. package es.carlosgarcia.android; 2. 3. /** 4. * Pequeo ejemplo de aplicacin mixta: Web y Nativa. Invocar desde JavaScript a la pa rte Nativa y viceversa. 5. * @author Carlos Garca Prez. 6. * @see http://carlos-garcia.es 7. */ 8. public interface MyAndroidToJsInterface { 9. public void metodoDemo1(); 10. public String metodoDemo2(); 11. }
es.carlosgarcia.android.WebDemoActivity

Actividad de la aplicacin.
view plainprint? 1. 2. 3. 4. 5. 6. 7. 8. 9. package es.carlosgarcia.android; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.View;

10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58.

import android.view.View.OnClickListener; import android.webkit.WebView; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; /** * Pequeo ejemplo de aplicacin mixta: Web y Nativa. Invocar desde JavaScript a la pa rte Nativa y viceversa. * @author Carlos Garca Prez. * @see http://carlos-garcia.es */ public class WebDemoActivity extends Activity implements MyAndroidToJsInterface, O nClickListener { private WebView browser; private EditText txt1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.main); browser = (WebView) findViewById(R.id.webview); Button btn1 = (Button) findViewById(R.id.btn1); txt1 = (EditText) findViewById(R.id.txt1); browser.getSettings().setJavaScriptEnabled(true); browser.addJavascriptInterface(this, "jsNativeInterface"); browser.loadUrl("file:///android_asset/carlos-garcia.html"); btn1.setOnClickListener(this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && browser.canGoBack()) { browser.goBack(); return true; } return super.onKeyDown(keyCode, event); } /** * Llamamos desde Android a Javascript * android.view.View.OnClickListener */ public void onClick(View v) { browser.loadUrl("javascript:callFromAndroidToJS('" + txt1.getText().toString() + "') "); } /**

59. 60. 61. 62. 63.

* Este mtodo es invocado desde JavaScript => Muestra un mensaje por pantalla * MyAndroidToJsInterface */ public void metodoDemo1() { Toast.makeText(this, "Invocado el metodo: metodoDemo1", Toast.LENGTH_SHOR T).show(); 64. } 65. 66. /** 67. * Este mtodo es invocado desde JavaScript => Devuelve un objeto JSON desde la a plicacin Nativa 68. * MyAndroidToJsInterface 69. */ 70. public String metodoDemo2() { 71. String toReturn = null; 72. 73. try { 74. JSONObject json = new JSONObject(); 75. json.put("timestamp", System.currentTimeMillis()); 76. json.put("autor", "http://www.carlos-garcia.es"); 77. toReturn = json.toString(); 78. } catch (JSONException e) { 79. // no se dar 80. } 81. 82. return toReturn; 83. } 84. 85. }

AndroidManifest.xml

Archivo de configuracin de la aplicacin.


view plainprint? 1. <?xml version="1.0" encoding="UTF-8"?> 2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3. package="es.carlosgarcia.android" 4. android:versionCode="1" 5. android:versionName="1.0"> 6. 7. <application android:icon="@drawable/icon" android:label="@string/app_name" a ndroid:debuggable="true"> 8. <activity android:name=".WebDemoActivity" android:label="@string/app_name" > 9. <intent-filter> 10. <action android:name="android.intent.action.MAIN" /> 11. <category android:name="android.intent.category.LAUNCHER" /> 12. </intent-filter> 13. </activity>

14. </application> 15. 16. <uses-sdk android:minSdkVersion="3" /> 17. <uses-permission android:name="android.permission.INTERNET"/> 18. </manifest>
+++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ Cdec base de datos package net.androoid.tutorial.basesdatosSimple; import java.util.ArrayList; import import import import import import android.app.ListActivity; android.database.Cursor; android.database.sqlite.SQLiteDatabase; android.os.Bundle; android.widget.ArrayAdapter; android.widget.ListAdapter;

/* La actividad ListActivity se utiliza para mostrar por pantalla * una lista de el ementos. Esta actividad alberga por defecto * un widget ListView al que se le asocia una fuente de datos como * por ejemplo una array o un Cursor. * Adems, la ListActivity trae tambin un layout por defecto que * consiste en una lista a pantalla complet a. */ public class BasesDatosSimple extends ListActivity { private final String BD_NOMBRE = "baseDatosSimple"; private final String BD_TABLA = "usuarios"; /** Se llama a este mtodo cuando accedemos a la Actividad por primera vez. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ArrayList<String> salida = new ArrayList<String>(); SQLiteDatabase myDB = null; /* Abrimos la base de datos. * Si no exista previamente se crear automticamente. */ myDB = this.openOrCreateDatabase(BD_NOMBRE, 1, null); /* Creamos la tabla de usuarios en la base de datos. * En caso de que existiera previamente no da error ('IF NOT EXISTS'). */ myDB.execSQL("CREATE TABLE IF NOT EXISTS " + BD_TABLA + " (nombre VARCHAR, apellido VARCHAR,"

+ " pais VARCHAR, edad INT(3));"); /* Introducimos un par de usuarios de ejemplo en la base de datos. */ myDB.execSQL("INSE RT INTO " + BD_TABLA + " (nombre, apellido, pais, edad)" + " VALUES ('Ingrid', 'Gonzalez', 'Spain', 20);"); myDB.execSQL("INSERT INTO " + BD_TABLA + " (nombre, apellido, pais, edad)" + " VALUES ('Ca rlos', 'Garcia', 'Peru', 30);"); /* Ahora hacemos una select sobre las columnas 'nombre' y 'edad' * para todos los usuarios mayores de 18 aos. * Slo mostraremos los primeros 7 usuarios. */ String[] columns = {"nombre","edad"}; Cursor c = myDB.query(BD_TABLA, columns, "edad > 18", null, null, null, null, "7"); /* Nos aseguramos de que se haya creado el cursor. */ if (c != null) { /* Obtenemos el ndice de las columnas que vamos a utilizar. */ int columnaNombreIndice = c.getColumnIndexOrThrow("nombre"); int columnaEdadIndice = c.getColumnIndexOrThrow("edad"); /* Creamos un entero a modo de contador * para listar los nombres por pantalla. */ int i = 1; /* El cursor devuelto est posicionado antes de la primera entrada. * Avanzamos una posicin. */ while (c.moveToNext()){ /* Obtenemos el valor de la columna nombre */ String valorColumnaNombre = c.getString(columnaNombreIndice); /* Obtenemos el valor de la columna edad */ int valorColumnaEdad = c.getInt(columnaEdadIndice); /* El nombre de una columna tambin * se puede recuperar mediante su ndice. * En este caso no es muy til por que ya * sabemos el nombre de la columna pero * os lo muestro a modo de ejemplo. */ String nombreColumnaEdad = c.getColumnName(columnaEdadIndice); /* Aadimos la entrada a la lista que mostraremos por pantalla. */ salida.add("" + i + ": " + valorColumnaNombre + " (" + nombreColumnaEdad + ": " + valorColumnaEdad + ")"); i++; }

} /* Cerramos la conexin a la base de datos */ if (myDB != null) myDB.close(); /* Las clases que implementan la interfaz ListAdapter se encargan de asociar * los datos que queremos mostrar por pantalla (nuestra arrayList 'salid a') * con el objeto ListView que alberga por defecto la actividad ListActivity. * En este caso utilizaremos un layout lineal vertical predefinido por Android. */ ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, salida); /* Asociamos el adaptador que acabamos de crear a esta actividad */ this.setListAdapter(adapter); } } ++++++++++++++++++++++++++++++++++++++++ http://www.edu4java.com/es/and roid/android8.htm l ++++++++++++++++++++++++++++++++++++++++++++++ http://www.comusoft.com/curso -de-backtrack-5-online +++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

na vez instalado el SDK de desarrollo de Android, Eclipse y el plug-in, vamos a empezar a desarrollar una eurocalculadora. No es que sea la aplicacin estrella de estas navidades, pero por algo se tiene que empezar.

Nota: En la versin actual de Android, la aplicacin se ver diferente a como se muestra en las capturas.

Para comenzar, dentro de Eclipse, creamos un nuevo proyecto.

Marcamos "Android Project" dentro de la categora "Android" y pulsamos "Next".

Ahora rellenamos los datos que definen nuestro proyecto.

A continuacin explico para qu sirve cada cosa:


y y

y y

Project name: Es el nombre que queramos darle al proyecto para el editor Eclipse. Package name: Deber de ser un nombre nico. No debera haber otra aplicacin con el mismo nombre. Google sugiere que como base pongas el nombre de tu compaa y despus el nombre de la aplicacin. Activity name: El nombre de la clase que implementar la actividad. Application name: El nombre que tendr nuestra aplicacin, que ser legible por un humano.

Pulsamos el botn "Finish".

Una vez se haya cargado el proyecto esqueleto, veamos lo que contiene "Eurocalculadora.java" haciendo doble clic sobre su nombre. (Hay que ir desplegando el arbol de elementos.)

Vemos que lo nico que hace cuando se carga es establecer una vista como interfaz de usuario de la aplicacin:

setContentView(R.layout.main)

Para ver qu es lo que se muestra vamos a ejecutar la aplicacin en el emulador, para ello, pulsamos sobre el men "Run" y despus sobre "Open Run Dialog...".

Aparecer un cuadro de dilogo. En el arbol de elementos de la izquierda, hacemos doble clic sobre "Android Application" para crear un nuevo entorno de ejecucin. Una vez hecho, en "Name:" establecemos el valor "Ejecucin normal" o lo que quieras poner. Despus pulsa sobre el botn "Browse..." selecciona el proyecto actual "Eurocalculadora". Pulsa "OK" y para terminar aplicando los cambios pulsa sobre "Apply".

En "Activity" tambin puede seleccionar la actividad que quieres iniciar. Por ahora, como slo tenemos una, lo vamos a dejar en blanco.

Como puedes ver, tenemos dos pestaas ms: "Emulator" y "Common":


y

En "Emulator" podremos seleccionar el tamao de la pantalla del terminal, la velocidad de la red, as como la latencia de la misma. (Tambin podremos especificar ciertos parmetros adicionales al emulador, como por ejemplo, para activar el sonido, para que cargue una tarjeta SD emulada, etc.) En "Common" varias opciones de ejecucin y depurado.

Si pulsas el botn "Run", se arrancar el emulador desde esta ventana de dilogo. Esta vez, vamos a pulsar sobre "Close" para cerrar esta ventana y ejecutar la aplicacin en el emulador mediante otro botn ms accesible.

La primera elipse roja marca donde hay que hacer clic para desplegar el men para depurar la aplicacin. La segunda elipse roja marca la zona donde hay que hacer clic para ejecutar la aplicacin. Como podrs ver, aparece un elemento llamado "Ejecucin normal". Vamos a hacerle clic para arrancar la aplicacin. Una vez cargado el emulador, que se lleva su tiempo, vers arrancar la aplicacin. (Recuerda no cerrar la aplicacin del emulador entre ejecucin y ejecucin de nuestra aplicacin. No es necesario.)

Por ahora la aplicacin no hace nada ms, as que vamos a remediarlo.

Lo primero de todo que haremos ser la interfaz de usuario de la misma. Recuerdas la instruccin que se ejecutaba nada ms arrancar la aplicacin?

setContentView(R.layout.main)

Especifica que se establezca la interfaz de usuario "main". Nosotros vamos a editarla. Para ello, hacemos doble clic al archivo "main.xml" que contiene esta interfaz de usuario.

Si no te aparece el texto que compone el archivo XML, pulsa sobre la pestaa de abajo que pone "Source" para verlo.

Para esta aplicacin queremos un formulario sencillo, algo parecido a esto:

Euros: ________________ Pesetas: ______________ [ [ Euros a pesetas Pesetas a Euros ] ]

Vamos a utilizar varios "LinearLayout" (Contenedores) para reorganizar los elementos. Un "LineraLayout" nos permitir alinear sus hijos en una sola direccin: Horizontal o vertical.

Como vemos en el esquema que acabo de poner, tenemos en un "LinearLayout" con disposicin vertical (que ocupar toda la zona disponible a interfz de usuario) cuatro entradas:

y y y y

Euros: ________________ Pesetas: ______________ [ [ Euros a pesetas Pesetas a Euros ] ]

Cada uno de estos elementos van dispuestos en orden vertical y hacia abajo.

Ahora bien... Qu pasa con "Euros: ________________ "?

Contiene dos elementos: unTextView (Para mostrar texto al usuario) y un EditText (Para que el usuario introduzca informacin en nuestra aplicacin) Qu hacemos si queremos tratarlos como uno? Pues los metemos dentro de otro "LinearLayout" con disposicin horizontal en los que estos dos elementos aparezcan uno detrs del otro.

Vamos a empezar a escribir el main.xml. Primera aproximacin. Vamos a intentar conseguir poner un TextView y un EditText juntos en la misma lnea.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/euros" /> <EditText android:id="@+id/euros" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>

La parte que est en verde define el LinearLayout que ocupar toda la pantalla y que contendr todos nuestros "controles":

android:layout_width="fill_parent" (Ancho) android:layout_height="fill_parent" (Alto)

layout_width="fill_parent" indicar que tomar el ancho total que le est dejando su padre, en este caso, la pantalla completa. Si pusiramos layout_width="wrap_content", estaramos indicando que queremos que tome de ancho el mnimo en el que entraran todos los hijos.

Tambin se especifica que la disposicin de los elementos ser en vertical (Podramos poner "horizontal" para disposicin horizontal):

android:orientation="vertical"

La parte de rojo define el LinearLayout que contiene el TextView y el EditText en una misma lnea en horizontal. Por eso se define como:

android:orientation="horizontal"

Para este LinearLayout se definen las siguientes propiedades:

android:layout_width="fill_parent" android:layout_height="wrap_content"

Con layout_width="fill_parent" estamos diciendo que tomaremos como ancho, todo el ancho que tenga disponible nuestro "contenedor" "padre". Y con layout_height="wrap_content" indicamos que queremos que como alto, ocupe lo mnimo posible como para contener y mostrar a los hijos: TextView y EditText.

Dentro de este LinearLayout tenemos los dos elementos. El primero:

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/euros" />

Que se renderizar con el alto y ancho mnimo para mostrar el texto asociado en el archivo de cadenas de texto. Como se puede ver, se ha especificado como texto "@string/euros". Con esto estamos diciendo que tome el valor de la clave "euros" dentro del archivo "strings.xml". Abrimos este archivo haciendole doble clic.

Y aadimos la entrada "euros". As quedar el archivo despus de aadir la entrada:

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Conversor</string> <string name="euros">Euros:</string> </resources>

En "name" est el nombre que le queremos dar para referenciarla y entre <string ...> y </string> el texto que queremos que contenga.

El segundo elemento que nos encontramos dentro de este LinearLayout es:

<EditText android:id="@+id/euros" android:layout_width="fill_parent" android:layout_height="wrap_content" />

En el que estamos definiendo un campo de entrada de texto con identificador euros, que en horizontal (layout_width) ocupa el resto de espacio que queda disponible para dibujarse ("fill_parent") y en vertical (layout_height) el mnimo espacio ("wrap_content").

Vamos a ejecutar la aplicacin a para ver cmo queda:

Vamos bien. Ahora slo tenemos que aadir ms de lo mismo para tener la otra fila. (Aadiendo un LinearLayout con un TextView y un TextEdit dentro.)

En el archivo main.xml aadimos el siguiente cdigo justo ntes del ltimo </LinarLayout>:

<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pesetas" /> <EditText android:id="@+id/pesetas" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>

Como podis ver, es exctamente igual que la fila inicial que hemos hecho, pero cambiando los valores.

Ahora tenemos que aadir una definicin de texto al archivo "strings.xml" para "@string/pesetas". Hay que ponerlo junto con todos los dems, justo debajo del que acabamos de aadir hace un momento.

<string name="pesetas">Pesetas:</string>

Volvemos a ejecutar la aplicacin para ver cmo va...

Recapitulemos... Tenemos un LinearLayout que representa a la pantalla completa que lista elementos en vertical. Los dos primeros elementos que aparecen son dos LinearLayout (Que dentro tienen dos elementos en horizontal.). Pues ahora, despus de estos dos LinearLayout, vamos a aadir dos botones.

Smplemente tenemos que aadir el siguiente cdigo al archivo "main.xml" justo ntes del ltimo </LinearLayout>:

<Button android:id="@+id/euros2pesetas" android:text="@string/euros2pesetas" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/pesetas2euros" android:text="@string/pesetas2euros" android:layout_width="wrap_content" android:layout_height="wrap_content" />

"@+id/pesetas2euros" sirve para indicar que queremos hacer referencia a este botn con el identificador pesetas2euros (Cosa que luego utilizaremos desde la programacin de la aplicacin). Cuando utilzamos "@string/pesetas2euros", estamos indicando que tome el texto que hace referencia a pesetas2euros en el archivo de cadenas de texto strings.xml.

Recordad aadir las definiciones de las cadenas de texto "euros2pesetas" y "pesetas2eutos" al archivo "strings.xml".

<string name="euros2pesetas">Convertir euros en pesetas</string> <string name="pesetas2euros">Convertir pesetas en euros</string>

Vamos a ejecutarlo a ver cmo va quedando...

Vis para qu sirve poner layout_width="wrap_content"? En este caso, los botones ocupan el mnimo ancho que pudieran ocupar. (Para que se vea su contenido correctamente.)

Y si yo quiero que los botones se alarguen y ocupen de ancho toda la ventana?

Pues les cambio el layout_width="wrap_content" por layout_width="fill_parent" . De esta forma, los botones tomarn tanto ancho como tenga el contenedor que los contiene. Ahora el cdigo XML de los botones quedan as:

<Button android:id="@+id/euros2pesetas" android:text="@string/euros2pesetas" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/pesetas2euros" android:text="@string/pesetas2euros" android:layout_width="fill_parent" android:layout_height="wrap_content" />

Volvemos a ejecutar y...

Ahora aparece como nosotros queramos.

Si. Muy bonito, pero no hace nada. Vamos a solucionarlo.

Si observamos el cdigo Eurocalculadora.java, la lnea:

public class Eurocalculadora extends Activity {

Sirve para indicar que nuestra Eurocalculadora hereda de Activity. Esto significa que nuestra Eurocalculadora la vamos a tratar como si fuera un objeto Activity. De hecho, con slo este gesto, ya funciona de la misma forma que Activity. Este objeto representa una actividad que el usuario puede realizar en nuestra aplicacin. Como seleccionar un punto en un mapa, seleccionar un contacto en su lista de contactos, o, como en este caso, convertir el valor de una moneda a otra. (Es muy importante conocer cmo funciona el ciclo de vida de este objeto. De todas formas, para este ejemplo no te har falta. Se hablar de ello en su momento.)

Para obtener los datos que el usuario introduzca en los EditText, necesitamos dos variables que los referencien. Una para cada campo. Para ello, vamos a aadir estos dos atributos a nuestra clase Eurocalculadora. Lo hacemos aadiendo las siguientes dos lneas al archivo Eurocalculadora.java justo debajo de "public class Eurocalculadora extends Activity {".

private EditText campoEuros; private EditText campoPesetas;

Los definimos como private porque no queremos que estn disponibles desde fuera de esta clase (Nuestra aplicacin). Y los establecemos como atributos de la clase, ya que necesitaremos que estn ah para acceder a ellos desde el manejador de acciones de los botones. (Cuando hagamos clic en algn botn necesitaremos acceder y cambiar los valores del EditText.)

Ahora obtenemos esto:

El texto EditText nos aparece subrayado con una lnea roja para indicarnos que el compilador no sabe de la existencia del objeto EditText. Para solucionarlo, vamos a utilizar una caracterstica del Eclipse. Pulsamos Control+Shift+O (Shift = Tecla situada normalmente encima de la tecla Ctrl de la izquierda) y el editor buscar donde est ese objeto y realizar la instruccin/es import correspondiente/s.

Como se puede observar, Eclipse nos ha aadido la lnea import android.widget.EditText, que indica dnde se encuentra la clase EditText. Ahora aparecen subrayadas en amarillo, pero simplemente es para indicarnos que hemos definido atributos que no se estn utilizando.

Ahora hay que hacer que cada uno de estos atributos hagan referencia a sus respectivos EditText, para ello, aadimos el siguiente cdigo justo debajo de setContentView(R.layout.main);

campoEuros = (EditText) findViewById(R.id.euros); campoPesetas = (EditText) findViewById(R.id.pesetas);

Mientras tecleas estas lneas, podrs ver cmo una vez que escribes R. te aparecen una serie de sugerencias, as como cuando escribes R.id. (Esta es la caracterstica de autocompletado de Eclipse.)

Ya tenemos las referencias a los campos de los valores... Ahora nos falta aadir una accin a cada botn. (Una que nos lea el valor escrito en campoEuros, nos lo convierta a pesetas y lo escriba en el campo de las pesetas. Lo mismo para la otra accin, pero al revs.)

Para aadir las acciones a cada botn, necesitamos hacer lo mismo que hemos hecho antes, pero esta vez slo aadiendo las siguientes lneas debajo de las anteriores y similares.

Button eurosAPesetas = (Button) findViewById(R.id.euros2pesetas); Button pesetasAEuros = (Button) findViewById(R.id.pesetas2euros);

Si observas bien, esta vez no hemos puesto Button euroAPesetas; como atributo de la clase, ya que slo necesitaremos la referencia a este control para aadirle el manejador de acciones. (Un objeto que sabe qu hacer ante cada evento que ocurra. En el caso del botn, cuando se le haga clic.)

Pulsamos Control+Shift+O y continuamos...

Por ahora vamos a aadir una accin tan sencilla como establecer un texto en cada EditText. Para ello aadimos el siguiente cdigo justo debajo de las dos ltimas lneas que hemos escrito.

eurosAPesetas.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { campoEuros.setText("Pulsacion eurosAPesetas..."); } }); pesetasAEuros.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { campoPesetas.setText("Pulsacion pesetasAEuros..."); } });

Aviso! No es recomendable introducir cadenas de texto directamente dentro del cdigo. Ya que nos encontraramos problemas a la hora de establecer varios idiomas para la misma. Lo hago aqu porque es una prueba que vamos a deshacer dentro de poco.

En este caso establecemos el manejador de la accin del clic mediante dando la orden setOnClickListener al atributo que representa el objeto del botn (eurosAPesetas). A la orden setOnClickListener le pasamos un callback que implementa el mtodo pblico onClick(View view), que ser el mtodo que se llame cuando el botn reciba un clic. Adivina. Cualquier cosa que pongamos dentro de la definicin de este mtodo ser ejecutado slo cuando se haga clic en el botn.

Para este ejemplo, si se pulsa algn botn ejecuto el cdigo: campoEuros.setText("Aqu pongo lo que quiera..."); Con el cdigo anterior le estoy diciendo al objeto referenciado por campoEuros (Que es un EditText) que establezca su contenido al texto que le estoy indicando.

Vamos a ejecutar, no sin antes pulsar Control+Shift+O, ya que la clase View nos aparece subrayada en rojo. (Otra cosa que puedes hacer para evitar tener que hacer esto es aadir manualmente cada include. Eso s, como es imposible saber donde est cada clase, debers de ver el listado de clases. Una vez pulses sobre la clase que ests usando, en este caso View, vers arriba del todo de la pgina que aparezca, en negrita y con texto grande la localizacin de la misma: android.view.View. Slo tendras que hacer el import correspondiente.)

Ahora s. Ejecutamos... Pulsamos el primer botn...

Al parece funciona. Ahora pulsamos el segundo botn...

Al pacere funciona... Ahora tenemos que hacer la conversin. Vamos ahora con el primer botn. Reemplazaremos:

eurosAPesetas.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { campoEuros.setText("Pulsacion eurosAPesetas..."); } });

por:

eurosAPesetas.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { campoPesetas.setText(""+Double.parseDouble(campoEuros.getText().toString())* 166.386); } });

Vamos a explicar lo que hace este chorizo...

campoPesetas.setText( "Aqu el texto que queramos poner" );

Esto est claro... Entre los parntesis ponemos el texto que queramos que aparezca en el EditText. En este caso queremos que aparezca el resultado de procesar:

Double.parseDouble(campoEuros.getText().toString())*166.386

Con campoEuros.getText().toString() obtenemos el nmero de euros introducido, pero como letras. (Una cadena de carcteres.) Para pasarlo a nmero, en este caso del tipo double.

Ejemplo: Double.parseDouble("132.55") nos devolver el valor de tipo double que representa 132.55, y no una cadena de texto que forme "132.55" con la cual no puedes realizar operaciones aritmticas.

As que todo esto: Double.parseDouble(campoEuros.getText().toString()) Es para obtener el valor numrico de los Euros con el cual podamos realizar la siguiente operacin, que ser multiplicarlo por 166.386 para convertirlo en pesetas.

Qu pintan las comillas en ""+Double.parseDouble(campoEuros.getText().toString())*166.386 ?

Es una forma muy cmoda de pasar de un valor decimal a una cadena de texto. (La conversin que hicimos antes era la inversa.)

Vamos a ejecutar el programa en el emulador para ver cmo va... (Introduzco un 6 en el campo Euros y pulso el primer botn.)

Parece que funciona... Pero qu pasa si en vez de un nmero introducimos una letra. Pues que obtendremos un error a la hora de convertir la cifra escrita a nmero. Cmo arreglamos esto? Tenemos dos soluciones. La primera y ms rpida es hacer que solo se puedan escribir nmeros:

En el main.xml (Donde definimos la interfaz de usuario) aadiramos el atributo android:numeric="decimal" a cada una de las etiquetas EditText. Ejemplo:

<EditText id="@+id/euros" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numeric="decimal" android:layout_weight="1"/> Cuando ponemos "decimal", le estamos indicando a Android que slo se aceptarn valores numricos en los que se permite utilizar decimales. Tambin podramos utilizar "signed" para indicar que la entrada sea numrica en la que se puede establecer el signo o "integer" para decir que la entrada sea numrica (un valor entero). Descargar proyecto hasta este punto (SDK 1.0) La forma ms larga... Reemplazando otra vez el cdigo de antes por:

eurosAPesetas.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { try{ campoPesetas.setText(""+Double.parseDouble(campoEuros.getText().toString())*166.3 86); }catch(Exception e){ campoPesetas.setText(getResources().getString(R.string.valorInvalido)); } } });

Y aadimos una nueva entrada al archivo strings.xml de la misma forma que estn las dems lneas dentro de este archivo.

<string name="valorInvalido">Valor introducido invlido!</string>

Qu hemos hecho? Pues hemos metido dentro de un bloque try ... catch la instruccin que puede provocar errores. (Lanzar excepciones) En el caso de que salte algn error en la ejecucin de cualquier instruccin de esta lnea, se ejecutara inminentemente el cdigo que est dentro del bloque catch(Exception e)

De esta forma, cuando introduzcamos alguna letra dentro del valor numrico y pulsemos el botn de convertir, en vez de mostrarnos la cantidad convertida, nos aparecer un mensaje de error.

Lo ms conveniente est en limitar a que el usuario introduzca siempre valores correctos. Por eso, siempre es ms aconsejable (y rpida) la primera opcin que hemos visto.

Ejercicio 1:

Realiza la programacin del otro botn. Es lo mismo que para el primer botn, slo que en vez de multiplicar "*", hay que dividir "/" y utilizar los nombres de las variables correctos.

Ejercicio 2:

Podras aadir un botn que al pulsarlo te borrara los dos campos?

Ahora vamos a aadir un botn para "Salir". Aadimos a strings.xml el texto del botn:

<string name="salir">Salir</string>

Aadimos a main.xml este botn, justo debajo de los dos que tenemos:

<Button android:id="@+id/salir" android:text="@string/salir" android:layout_width="fill_parent" android:layout_height="wrap_content" />

El botn tendr identificador salir y tomar el texto de strings.xml con nombre (name) salir. (El que acabamos de incluir.)

Ahora aadimos unas cuantas lneas a Eurocalculadora.java. Justo despus de obtener las referencias a los otros dos botones (y ntes de establecer las acciones de los mismos) aadimos la referencia al nuevo botn:

Button salir = (Button) findViewById(R.id.salir);

Y le establecemos su funcionalidad. (Debajo de las acciones de los dos botones.)

salir.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); finish(); } });

Queda claro, salimos de la aplicacin indicando que todo fu correcto. Es la forma que tenemos de decir que hemos finalizado la actividad actual.

Ejecutamos la aplicacin...

Pulsamos el botn Salir y funciona correctamente, la aplicacin sale.

Descargar proyecto hasta este punto (SDK 1.0) Ahora vamos a aadir un pequeomen para realizar las tres acciones que hacen los botones. Para esto necesitamos definir tres constantes para tener referencia a cada accin. En Eurocalculadora, justo debajo de:

private EditText campoEuros; private EditText campoPesetas;

Aadimos:

private static final int EUROS_EN_PESETAS = Menu.FIRST; private static final int PESETAS_EN_EUROS = Menu.FIRST + 1; private static final int SALIR = Menu.FIRST + 2;

Lo que hemos hecho es dar un valor numrico a cada una de estas constantes que representar a un elemento del men, el valor numrico comienza por el valor que nos devuelva Menu.FIRST y vamos tomando los siguientes... Pulsamos Control+Shift+O para importar la clase Menu en el archivo de forma automtica.

Vamos a aadir dos nuevas cadenas de texto. Ya que en los botones del men no entran todo el texto de un botn.

<string name="m_euros2pesetas">Euros a pesetas</string> <string name="m_pesetas2euros">Pesetas a euros</string>

Ahora, tenemos que sobreescribir el mtodo que crea el men, que por defecto crea un men vaco. As que justo debajo de las lneas anteriores escribimos lo siguiente:

@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, EUROS_EN_PESETAS, 0, R.string.m_euros2pesetas); menu.add(Menu.NONE, PESETAS_EN_EUROS, 1, R.string.m_pesetas2euros); menu.add(Menu.NONE, SALIR, 2, R.string.salir); return true; }

Explicamos paso a paso... Como podemos observar en rojo, se nos pasa el objeto men para que nosotros, llamando a sus mtodos, lo vayamos rellenando.

Utilizamos menu.add para aadir un elemento del men, en el primer caso, no asignamos el elemento del men a ningn grupo, el siguiente parmetro del elemento servir de identificador el valor de la constante EUROS_EN_PESETAS y contendr el texto que definimos en el archivo de cadenas de texto strings.xml. En este caso, vamos a reutilizar las cadenas que establecimos para los botones.

(El valor 0 es la posicin en el men, por eso mismo el men de abajo tiene posicin 1 y el de salir la posicin 2)

Vamos a ejecutar para ver cmo se ve... (El aspecto del men que obtendrs t ser distinto)

Tiene buena pinta. Ahora slo tenemos que darle funcionalidad. Para ello, vamos a sacar cada accin de cada botn a parte en forma de mtodo de la clase Eurocalculadora.

Para ello, slo tenemos que aadir el siguiente cdigo justo debajo del que generaba el men.

public void f_euros_a_pesetas() { campoPesetas.setText(""+Double.parseDouble(campoEuros.getText().toString())*166.3 86); } public void f_pesetas_a_euros() { campoEuros.setText(""+Double.parseDouble(campoPesetas.getText().toString())/166.3 86); } public void f_salir() { setResult(RESULT_OK); finish(); }

Tal y como hemos hecho, hemos definido tres mtodos para esta clase. Los tres son pblicos y no devuelven nada como resultado de su ejecucin (void). El codigo que aparece en el mtodo f_salir, es el cdigo que se debe escribir para indicar que una actividad ha salido de su ejecucin de forma correcta.

Reemplazamos el cdigo de las acciones de los botones, para que se parezcan al siguiente:

eurosAPesetas.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { f_euros_a_pesetas(); } }); pesetasAEuros.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { f_pesetas_a_euros(); } }); salir.setOnClickListener(new View.OnClickListener() { public void onClick(View view) {

f_salir(); } });

Donde antes estaba la accin, ahora se llama al mtodo que realiza esa accin.

Igual que antes, que sobreescribimos el mtodo que configuraba el men para que se generara el men que nosotros hemos querido, ahora vamos a sobreescribir el mtodo que se encarga de procesar la accin de seleccin de un elemento del men. En este caso ser para realizar una conversin, o para salir. Al final del todo escribimos el siguiente cdigo:

@Override public boolean onMenuItemSelected(int featureId, MenuItem item) { super.onMenuItemSelected(featureId, item); switch(item.getItemId()) { case EUROS_EN_PESETAS: f_euros_a_pesetas(); break; case PESETAS_EN_EUROS: f_pesetas_a_euros(); break; case SALIR: f_salir(); break; } return true; }

Como hemos dicho antes, cuando un usuario selecciona un elemento del men, se llamar a este mtodo automaticamente, pasndonos entre otras cosas, el elemento que hemos seleccionado del men en forma de variable llamada item. Le enviamos el mensaje .getItemId() para obtener el identificador del elemento en cuestin. Qu hacemos entonces? Pues dependiendo del elemento al que hayamos seleccionado, llamamos a un mtodo u otro. Si hicimos clic sobre el item con id SALIR, llamaremos a f_salir() y as...

Ejecutamos la aplicacin y podemos comprobar que el men funciona perfectamente. Ahora bien... Qu pasa si no escribimos ningn nmero e intentamos realizar cualquier

accin? Pues que la aplicacin falla. Para no complicarlo ms, he decidido no continuar con este ejemplo.

Descargar proyecto hasta este punto (SDK 1.0)

Prueba a aadir iconos a cada elemento del men. El punto donde puedes hacerlo es cuando aades cada elemento al men, pero esta vez as:

menu.add(Menu.NONE, EUROS_EN_PESETAS, 0, R.string.m_euros2pesetas).setIcon(R.drawable.nombreDeTuIcono);

Tambin puedes contemplar el caso en el que no haya nada dentro del campo de euros y pulses sobre el botn para convertir de euros a pesetas...

Vous aimerez peut-être aussi