Después de instalar nuestro entorno de desarrollo para Android y comentar la estructura básica de un proyecto y los diferentes componentes software que podemos utilizar ya es hora de empezar a escribir algo de código. Y como siempre lo mejor es empezar por escribir una aplicación sencilla.

En un principio me planteé analizar en este post el clásico Hola Mundo pero más tarde me pareció que se iban a quedar algunas cosas básicas en el tintero. Así que he versionado a mi manera el Hola Mundo transformándolo en algo así como un Hola Usuario, que es igual de sencilla pero añade un par de cosas interesantes de contar. La aplicación constará de dos pantallas, por un lado la pantalla principal que solicitará un nombre al usuario y una segunda pantalla en la que se mostrará un mensaje personalizado para el usuario. Sencillo, inútil, pero aprenderemos muchos conceptos básicos, que para empezar no está mal.

Hola Usuario Pantalla 1Hola Usuario Pantalla 2

En primer lugar vamos a crear un nuevo proyecto Android tal como vimos al final del primer post de la serie. Llamaremos al proyecto “HolaUsuario”, indicaremos como target por ejemplo “Android 1.6″, daremos un nombre a la aplicación e indicaremos que se cree una actividad llamada “HolaUsuario”.

Nuevo Proyecto Hola Usuario

Como ya vimos esto nos crea la estructura de carpetas del proyecto y todos los ficheros necesarios de un Hola Mundo básico, es decir, una sola pantalla donde se muestra únicamente un mensaje fijo.

Lo primero que vamos a hacer es diseñar nuestra pantalla principal modificando la que Eclipse nos ha creado por defecto. ¿Pero dónde y cómo se define cada pantalla de la aplicación? En Android, el diseño y la lógica de una pantalla estan separados en dos ficheros distintos. Por un lado, en el fichero  /res/layout/main.xml tendremos el diseño puramente visual de la pantalla definido como fichero XML y por otro lado, en el fichero  /src/paquetejava/HolaUsuario.java, encontraremos el código java que determina la lógica de la pantalla.

Vamos a modificar en primer lugar el aspecto de la ventana principal de la aplicación añadiendo los controles (views) que vemos en la primera captura de pantalla. Para ello, vamos a sustituir el contenido del fichero main.xml por el siguiente:

<?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" >

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

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

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

</LinearLayout>

En este XML se definen los elementos visuales que componen la interfaz de nuestra pantalla principal y se especifican todas sus propiedades. No nos detendremos mucho en cada detalle porque ése será tema de otro artículo, pero expliquemos un poco lo que vemos en el fichero.

Lo primero que nos encontramos es un elemento LinearLayout. Los layout son elementos no visibles que determinan cómo se van a distribuir en el espacio los controles que incluyamos en su interior. Los programadores java, y más concretamente de Swing, conocerán este concepto perfectamente. En este caso, un LinearLayout distribuirá los controles uno tras otro y en la orientación que indique su propiedad android:orientation.

Dentro del layout hemos incluido 3 controles: una etiqueta (TextView), un cuadro de texto (EditText), y un botón (Button). En todos ellos hemos establecido las siguientes propiedades:

  • android:id. ID del control, con el que podremos identificarlo más tarde en nuestro código.Vemos que el identificador lo escribimos precedido de “@+id/”. Esto tendrá como efecto que al compilarse el proyecto se genere automáticamente una nueva constante en la clase R para dicho control [Aprende más sobre la clase R en el post anterior].
  • android:text. Texto del control. El texto de un control se puede especificar directamente o bien utilizar alguna de las cadenas de texto definidas en los recursos del proyecto (fichero strings.xml), en cuyo caso indicaremos su identificador precedido del prefijo “@string/”.
  • android:layout_height y android:layout_width. Dimensiones del control con respecto al layout que lo contiene. Esta propiedad tomará normalmente los valores “wrap_content” para indicar que las dimensiones del control se ajustarán al contenido del mismo, o bien “fill_parent” para indicar que el ancho o el alto del control se ajustará al ancho o alto del layout contenedor respectivamente.

Con esto ya tenemos definida la presentación visual de nuestra ventana principal de la aplicación. De igual forma definiremos la interfaz de la segunda pantalla, creando un nuevo fichero llamado frmmensaje.xml, y añadiendo esta vez tan solo una etiqueta (TextView) para mostrar el mensaje personalizado al usuario. Veamos cómo quedaría nuestra segunda pantalla:

<?xml version="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">

<TextView android:id="@+id/TxtMensaje"
	android:layout_height="wrap_content"
	android:layout_width="fill_parent"
	android:text="$mensaje"></TextView>

</LinearLayout>

Una vez definida la interfaz de las pantallas de la aplicación deberemos implementar la lógica de la misma. Como ya hemos comentado, la lógica de la aplicación se definirá en ficheros java independientes. Para la pantalla principal ya tenemos creado un fichero por defecto llamado HolaUsuario.java. Empecemos por comentar su código por defecto:

public class HolaUsuario extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Como ya vimos en un post anterior, las diferentes pantallas de una aplicación Android se definen mediante objetos de tipo Activity. Por tanto, lo primero que encontramos en nuestro fichero java es la definición de una nueva clase HolaUsuario que extiende a Activity. El único método que sobreescribiremos de esta clase será el método OnCreate, llamado cuando se crea por primera vez la actividad. En este método lo único que encontramos en principio, además de la llamada a su implementación en la clase padre, es la llamada al método setContentView(R.layout.main). Con esta llamada estaremos indicando a Android que debe establecer como interfaz gráfica de esta actividad la definida en el recurso R.layout.main, que no es más que la que hemos especificado en el fichero /res/layout/main.xml. Una vez más vemos la utilidad de las diferentes constantes de recursos creadas automáticamente en la clase R al compilar el proyecto.

En principio vamos a crear una nueva actividad para la segunda pantalla de la aplicación análoga a ésta primera, para lo que crearemos una nueva clase FrmMensaje que exienda de Activity y que implemente el método onCreate indicando que utilice la interfaz definida en R.layout.frmmensaje.

public class FrmMensaje extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frmmensaje);
    }
}

Como vemos, el código incluido por defecto en estas clases lo único que hace es generar la interfaz de la actividad. A partir de aquí nosotros tendremos que incluir el resto de la lógica de la aplicación. Y vamos a empezar con la actividad principal HolaUsuario, obteniendo una referencia a los diferentes controles de la interfaz que necesitemos manipular, en nuestro caso sólo el cuadro de texto y el botón. Para ello utilizaremos el método findViewById() indicando el ID de cada control, definidos como siempre en la clase R:

final EditText txtNombre = (EditText)findViewById(R.id.TxtNombre);
final Button btnHola = (Button)findViewById(R.id.BtnHola);

Una vez tenemos acceso a los diferentes controles, ya sólo nos queda implementar las acciones a tomar cuando pulsemos el botón de la pantalla. Para ello implementaremos el evento onClick de dicho botón, veamos cómo:

btnHola.setOnClickListener(new OnClickListener() {
	@Override
	public void onClick(View arg0) {
		Intent intent = new Intent(HolaUsuario.this, FrmMensaje.class);

		Bundle bundle = new Bundle();
		bundle.putString("NOMBRE", txtNombre.getText().toString());
		intent.putExtras(bundle);

		startActivity(intent);
	}
});

Como ya indicamos en el artículo anterior, la comunicación entre los distintos componentes y aplicaciones en Android se realiza mediante intents, por lo que el primer paso será crear un objeto de este tipo. Existen varias variantes del constructor de la clase Intent, cada una de ellas dirigida a unas determinadas acciones, pero en nuestro caso particular vamos a utilizar el intent para llamar a una actividad desde otra de la misma aplicación, para lo que pasaremos al constructor una referencia a la propia actividad llamadora (HolaUsuario.this), y la clase de la actividad llamada (FrmMensaje.class).

Si quisiéramos tan sólo mostrar una nueva actividad ya tan sólo nos quedaría llamar a startActivity() pasándole como parámetro el intent creado. Pero en nuestro ejemplo queremos también pasarle cierta información a la actividad, concretamente el nombre que introduzca el usuario en el cuadro de texto. Para hacer esto vamos a crear un objeto Bundle, que puede contener una lista de pares clave-valor con toda la información a pasar entre las actividades. En nuestro caso sólo añadiremos un dato de tipo String mediante el método putString(clave, valor). Tras esto añadiremos la información al intent mediante el método putExtras(bundle).

Finalizada la actividad principal de la aplicación pasamos ya a la secundaria. Comenzaremos de forma análoga a la anterior, ampliando el método onCreate obteniendo las referencias a los objetos que manipularemos, esta vez sólo la etiqueta de texto. Tras esto viene lo más interesante, debemos recuperar la información pasada desde la actividad principal y asignarla como texto de la etiqueta. Para ello accederemos en primer lugar al intent que ha originado la actividad actual mediante el método getIntent() y recuperaremos su información asociada (objeto Bundle) mediante el método getExtras().

Hecho esto tan sólo nos queda construir el texto de la etiqueta mediante su método setText(texto) y recuperando el valor de nuestra clave almacenada en el objeto Bundle mediante getString(clave).

public class FrmMensaje extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frmmensaje);

        TextView txtMensaje = (TextView)findViewById(R.id.TxtMensaje);

        Bundle bundle = getIntent().getExtras();

        txtMensaje.setText("Hola " + bundle.getString("NOMBRE"));
    }
}

Con esto hemos concluido la lógica de las dos pantallas de nuestra aplicación y tan sólo nos queda un paso importante para finalizar nuestro desarrollo. Como indicamos en uno de los artículos anteriores, cualquier aplicación Android utiliza un fichero especial en formato XML (AndroidManifest.xml) para definir, entre otras cosas, los diferentes elementos que la componen. Por tanto, todas las actividades de nuestra aplicación deben quedar convenientemente recogidas en este fichero. La actividad principal ya debe aparecer puesto que se creó de forma automática al crear el nuevo proyecto Android, por lo que debemos añadir tan sólo la segunda. Para este ejemplo nos limitaremos a incluir la actividad en el XML, más adelante veremos que opciones adicionales podemos especificar.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="net.sgoliver"
      android:versionCode="1"
      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".HolaUsuario"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    	<activity android:name=".FrmMensaje"></activity>
     </application>

    <uses-sdk android:minSdkVersion="4" />

</manifest>

Una vez llegado aquí, si todo ha ido bien, deberíamos poder ejecutar el proyecto sin errores y probar nuestra aplicación en el emulador.

Descarga el código fuente de este artículo.

Espero que esta aplicación de ejemplo os haya servido para aprender temas básicos en el desarrollo para Android, como por ejemplo la definición de la interfaz gráfica, el código java necesario para acceder y manipular los elementos de dicha interfaz, o la forma de comunicar diferentes actividades de Android. En los artículos siguientes veremos algunos de estos temas de forma más específica y ampliaremos con algunos temas más avanzados.

, , , , , ,

Algunos recursos con información valiosa sobre ASP.NET MVC:

  • La propia web oficial de ASP.NET MVC, con gran cantidad de información, tutoriales, videos, ejemplos…
  • La documentación oficial de ASP.NET MVC en MSDN.
  • Una lista de 10 cuestiones básicas sobre ASP.NET MVC que pueden ayudar a aclarar algunas dudas iniciales [Edito: Actulización de la lista de preguntas para la versión ASP.NET MVC 1.0].
  • Una serie de artículos de Scott Guthrie en cuatro entregas [1, 2, 3, 4].
  • Recordar también que el propio Scott Guthrie publicó en su blog hace unos días un fantástico tutorial de 185 páginas sobre ASP.NET MVC que forma parte del libro Professional ASP.NET MVC y cuyo enlace de descarga podéis encontrar en la entrada que dedicamos a dicha noticia.
  • Otro buen recurso de información sobre ASP.NET MVC es el ASP.NET MVC Training Kit publicado por Microsoft, que contiene entre otros Hand On Labs, demos y presentaciones sobre el framework.
  • Como utilizar ejemplos es casi siempre la mejor forma de aprender, os paso también una lista de aplicaciones de ejemplo [open source] construídas con ASP.NET MVC.
  • Y por último un par de artículos sobre consejos o buenas prácticas a la hora de utilizar ASP.NET MVC que pueden ayudarnos a hacer menos laboriosas algunas tareas.

Suficiente por el momento para comenzar a utilizar este fantástico framework.

, , , , ,

Ejemplo JExcel

En esta página se muestra un programa java completo como ejemplo de uso de la librería JExcelApi. Puedes encontrar mucha más información sobre esta librería en el artículo original que contiene este ejemplo.

import java.io.*;
import java.util.Date;
import jxl.*;
import jxl.read.biff.BiffException;
import jxl.write.*; 

public class DemoJExcel
{
    public static void main(String[] args)
    {
        escribirExcel();

        leerExcel();

        System.out.println("Ejemplo Finalizado.");
    }

    public static void escribirExcel()
    {
        try
        {
            //Se crea el libro Excel
            WritableWorkbook workbook =
                    Workbook.createWorkbook(new File("ejemplo.xls")); 

            //Se crea una nueva hoja dentro del libro
            WritableSheet sheet =
                    workbook.createSheet("HojaEjemplo", 0); 

            //Creamos celdas de varios tipos
            sheet.addCell(new jxl.write.Number(0, 0, 1));
            sheet.addCell(new jxl.write.Number(1, 0, 1.2));
            sheet.addCell(new jxl.write.Label(2, 0, "ejemplo"));
            sheet.addCell(new jxl.write.Boolean(3,0,true)); 

            //Creamos una celda de tipo fecha y la mostramos
            //indicando un patón de formato
            DateFormat customDateFormat =
                    new DateFormat ("d/m/yy h:mm"); 

            WritableCellFormat dateFormat =
                    new WritableCellFormat (customDateFormat); 

            sheet.addCell(new jxl.write.DateTime(4, 0, new Date(), dateFormat));

            //Escribimos los resultados al fichero Excel
            workbook.write();
            workbook.close(); 

            leerExcel();

            System.out.println("Ejemplo finalizado.");
        }
        catch (IOException ex)
        {
            System.out.println("Error al crear el fichero.");
        }
        catch (WriteException ex)
        {
            System.out.println("Error al escribir el fichero.");
        }
    }

    public static void leerExcel()
    {
        try
        {
            //Se abre el fichero Excel
            Workbook workbook = Workbook.getWorkbook(new File("ejemplo.xls")); 

            //Se obtiene la primera hoja
            Sheet sheet = workbook.getSheet(0); 

            //Se leen las primeras 5 celdas
            for(int i=0; i<5; i++)
            {
                //Se obtiene la celda i-esima
                Cell cell = sheet.getCell(i,0);

                //Se imprime en pantalla la celda según su tipo
                if (cell.getType() == CellType.NUMBER)
                {
                    System.out.println("Número: " + ((NumberCell)cell).getValue());
                }
                else if (cell.getType() == CellType.LABEL)
                {
                    System.out.println("String: " + ((LabelCell)cell).getString());
                }
                else if (cell.getType() == CellType.BOOLEAN)
                {
                    System.out.println("Boolean: " + ((BooleanCell)cell).getValue());
                }
                else if (cell.getType() == CellType.DATE)
                {
                    System.out.println("Fecha: " + ((DateCell)cell).getDate());
                }
            }
        }
        catch (Exception ex)
        {
            System.out.println("Error!");
        }
    }
}
, , ,

Ejemplo Jakarta POI

En esta página se muestra un programa java completo como ejemplo de uso de la librería Jakarta POI. Puedes encontrar mucha más información sobre esta librería en el artículo original que contiene este ejemplo.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

public class DemoPOI
{
    public static void main(String[] args)
    {
        escribirExcel();

        leerExcel();

        System.out.println("Ejemplo Finalizado.");
    }

    public static void escribirExcel()
    {
        try
        {
            //Se crea el libro Excel
            HSSFWorkbook wb = new HSSFWorkbook();

            //Se crea una nueva hoja dentro del libro
            HSSFSheet sheet = wb.createSheet("HojaEjemplo");

            //Se crea una fila dentro de la hoja
            HSSFRow row = sheet.createRow((short)0);

            //Creamos celdas de varios tipos
            row.createCell((short)0).setCellValue(1);
            row.createCell((short)1).setCellValue(1.2);
            row.createCell((short)2).setCellValue("ejemplo");
            row.createCell((short)3).setCellValue(true);

            //Creamos una celda de tipo fecha y la mostramos
            //indicando un patrón de formato
            HSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setDataFormat(
                    HSSFDataFormat.getBuiltinFormat("d/m/yy h:mm"));

            HSSFCell cell = row.createCell((short)4);
            cell.setCellValue(new Date());
            cell.setCellStyle(cellStyle);

            //Escribimos los resultados a un fichero Excel
            FileOutputStream fileOut =
                new FileOutputStream("ejemplo.xls");

            wb.write(fileOut);
            fileOut.close();
        }
        catch(IOException e)
        {
            System.out.println("Error al escribir el fichero.");
        }
    }

    public static void leerExcel()
    {
        try
        {
            //Se abre el fichero Excel
            POIFSFileSystem fs =
                    new POIFSFileSystem(
                            new FileInputStream("c:ejemplo.xls"));

            //Se obtiene el libro Excel
            HSSFWorkbook wb = new HSSFWorkbook(fs);

            //Se obtiene la primera hoja
            HSSFSheet sheet = wb.getSheetAt(0);

            //Se obtiene la primera fila de la hoja
            HSSFRow row = sheet.getRow(0);

            //Se leen las primeras 5 celdas
            for(int i=0; i<5; i++)
            {
                //Se obtiene la celda i-esima
                HSSFCell cell = row.getCell((short)i);

                //Si la celda leida no está vacía
                if (cell != null)
                {
                    //Se imprime en pantalla la celda según su tipo
                    switch(cell.getCellType())
                    {
                        case HSSFCell.CELL_TYPE_NUMERIC:
                            System.out.println("Número: " + cell.getNumericCellValue());
                            break;
                        case HSSFCell.CELL_TYPE_STRING:
                            System.out.println("String: " + cell.getStringCellValue());
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN:
                            System.out.println("Boolean: " + cell.getBooleanCellValue());
                            break;
                        default:
                            System.out.println("Default: " + cell.getDateCellValue());
                            break;
                    }
                }
            }
        }
        catch(IOException ex)
        {
            System.out.println("Error al leer el fichero.");
        }
    }
}
, , ,