miércoles, 3 de abril de 2013

Android: Crear una aplicación básica


Partiendo como base del post anterior para crear un proyecto básico (yo lo he montado para compilar con Android 4.0, por aquello de hacerlo compatible 100% con mi teléfono) vamos a crear una aplicación tan simple como sea posible pero que nos ilustre como trabajar con Android.

Objetivo

El objetivo será crear una aplicación de dos pantallas con la siguiente funcionalidad:
  • Pantalla Principal:
    • Botón para cambiar un texto.
    • Botón para ir a la pantalla secundaria.
  • Pantalla secundaria:
    • Mostar un texto que le hemos pasado  desde la pantalla principal.


Comenzamos el desarrollo

Si vamos a desplegar esta aplicación en nuestro dispositivo para las pruebas, lo primero que tendremos que hacer es establecer la propiedad debbugable a true en el archivo AndroidManifest.xml.



En nuestro proyecto tendremos dos carpetas principales con las que trabajaremos:
  • SRC contiene el código java de la aplicación
  • RES/LAYOUT contiene los XML de las pantallas que desarrollaremos




Tras esto, abriremos nuestro layout principal, que si lo hemos creado por defecto se llamará activity_main.xml y lo podremos localizar en res > layout.




Añadiremos dos Buttons y un TextView (arrastrando y soltando). Y sobre cada elemento haremos click derecho y Edit ID… para cambiarle su identificador por estos:
  • TextView: txtTextoPrincipal
  • Button 1: btnCambiarTexto (cambiar con Edit Text… el texto a “Cambiar Texto”)
  • Button2: btnIrASecundaria (cambiar con Edit Text… el texto a “Ir a Pantalla Secundaria”)



Nos quedará algo así:



Podemos ver en la segunda pestaña inferior el código XML de la pantalla. Es interesante pues la verdad es que la interfaz gráfica no es muy buena a la hora de colocar bien los elementos, y siempre se acaba toquetenando el XML.



Manos en el código: cambiar el texto

Cada layout deberá tener asociado una clase java en el SRC. En este caso, al ser la aplicación por defecto, nos habrá creado un paquete con la clase MainActivity, que abriremos.



Por defecto, dejamos el onCreate como está, añadiendo simplemente la llamada a la función cargarObjetosPantalla que posteriormente definiremos dentro de la clase:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cargarObjetosPantalla();
    }

A continuación, dentro de nuestra clase definimos el método que obtendrá los elementos del archivo xml (layout) y lo asociará a fields de la clase que iremos creando. Es recomendable usar para estos fields los mismos nombres que hayamos usado en los identificadores del layout.
Para obtener los campos usaremos la función findViewById que nos devuelve el objeto (al que deberemos hacer cast a su tipo) del xml R.id (nos devuelve los ids de los xml definidos en layaout).

textView1 = (TextView)findViewById(R.id.textView1);

Como no hemos definido el objeto textView1 en la clase, nos dará un error, pero con las sugerencias nos dejará crearlo de forma rápida.



Quedando así la definición del campo:



Una vez tenemos los 3 objetos ya creados, vamos a montar los eventos onClick para los botones.
Simplemente debemos añadirle un onClickEventListener que crearemos directamente:

       btnCambiarTexto.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                           // TODO Auto-generated method stub
                          
                    }
             });

Aunque lo hagamos con ambos, para una primera prueba, lo interesante es hacerlo con btnCambiarTexto. En este caso, cuando hagamos click en dicho botón cambiará el texto de txtTextoPrincipal por lo que queramos, y esto se haría sustituyendo el TODO por el código siguiente:

txtTextoPrincipal.setText("has cambiado el texto con el boton");

Y lo mejor, antes se seguir, es probar nuestro código. Para ello, sobre el proyecto hacemos click derecho y Run As > Android Application…

Crear un nuevo layout

Ahora vamos a complicarlo un poco más: vamos a crear una nueva pantalla que será nuestra pantalla secundaria y que llamaremos activity_secundaria.xml.
Sobre la carpeta layout, haremos click derecho > New > Other



Y en el asistente seleccionaremos Android XML File.



En File indicaremos activity_secundaria.xml y en Root Element seleccionaremos Relative Layout.



Pulsamos Finish y nos creará nuestra pantalla.
Sobre esta pantalla añadiremos un TextView y le cambiaremos el id por txtTextoSecundario.




Como he comentado antes, cada layout suele tener asociada su clase, por lo que en nuestro paquete java dentro del directorio SRC crearemos una clase que llamaremos ActivitySecundaria y que extenderá de android.app.Activity.



En esta clase, crearemos el método onCreate que de la misma forma que se define en la clase MainActivity, pero cambiando el layout de referencia por el de la pantalla secundaria:

       @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_secundaria);
    }

¿Con esto ya tendríamos lista la pantalla? Pues no. Tendremos que añadir la actividad al AndroidManifest.xml. Para ello, abrirmos el archivo, navegamos a la pestaña Aplicación, clicamos en Add y eleccionamos Activity.

Tras esto, seleccionamos la actividad añadida y con el Browse de Name buscamos nuestra actividad (ActivitySecundaria). En Label indicaremos el nombre que se haya definido en la aplicación, es decir @string/app_name, y salvamos.



Codificando la transición entre pantallas

Ahora sí que tendríamos la pantalla secundaria lista para verla, pero para acceder a ella desde la principal, tendremos que iremos a la clase MainActivity rellenar el evento onClick del botón btnIrASecundaria que es el que la invocará.

btnIrASecundaria.setOnClickListener(new OnClickListener() {
       public void onClick(View v) {
             Intent intento = new Intent(MainActivity.this,
                                    ActivitySecundaria.class);
             startActivity(intento);
       }
});

Como ves, creamos un objeto de tipo Intent, que Android intentará ejecutar y lo llevará a cabo si puede. En caso contrario, pues simplemente no lo ejecutará. En este objeto indicamos que vamos a hacer un intento desde nuestro contexto (MainActivity.this) a la clase que a la que queremos ir (ActivitySecundaria.class). Finalmente, con el método startActivity se intenta ejecutar.

Con esto, ya podemos probar y ver como desde el botón btnIrASecundaria nos lleva a la pantalla secundaria, y desde el botón volver de nuestro dispositivo, volveremos a la principal.

Paso de datos entre pantallas

Ahora vamos a pasarle datos a la pantalla haciendo uso del objeto intento y de su método putExtra, que nos permite añadir un objeto identificado con un nombre y su valor (por ejemplo string):

intento.putExtra("texto", "texto enviado desde la pantalla principal");

Con lo que el código del onClick nos queda así:

Intent intento = new Intent(MainActivity.this, ActivitySecundaria.class);
intento.putExtra("texto", "texto enviado desde la pantalla principal");
startActivity(intento);

No obstante, esto solo nos envía el texto, ahora desde ActivitySecundaria, en el método onCreate deberemos capturarlo. Para ello, comenzaremos por crearnos el método cargarObjetosPantalla e invocarlo desde el onCreate.

       @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_secundaria);
        cargarObjetosPantalla();
    }

Una vez dentro, capturamos el TextView txtTextoSecundario y creamos su correspondiente campo.

txtTextoSecundario = (TextView)findViewById(R.id.txtTextoSecundario);

A continuación crearemos una variable de tipo String, y con el this.getIntent() obtendremos el intento. De aquí obtendremos los extras que trae con getExtras(), lo cual nos devuelve un vector, y siemplemente buscaremos por el identificador que establecimos (text).

String str = (String) this.getIntent().getExtras().get("texto");

Finalmente, lo asignamos a nuestro txtTextoSecundario:

txtTextoSecundario.setText(str);

Con lo que nos quedará listo para ejecutar.

public void cargarObjetosPantalla()
{
       txtTextoSecundario = (TextView)findViewById(R.id.txtTextoSecundario);
       String str = (String) this.getIntent().getExtras().get("texto");
       txtTextoSecundario.setText(str);
}

Pido disculpas por un post tan intenso, pero espero que todos y cada uno de los pasos haya sido compresible.

Código de ejemplo aquí