Tutorial CRUD Android + SQLite (III): Mostrar datos en Formulario

Posted by in Programación Android

Siguiendo con el Tutorial Android + SQLite en la entrada anterior vimos cómo mostrar en un listview registros de la base de datos SQLite para la aplicación CRUD de condiciones para la solicitud de una hipoteca. En la entrada actual mostraremos los registros de forma individual en un formulario profundizando en los siguientes conceptos:

  • Evento onListItemClick en ListView al seleccionar un registro
  • Navegar entre Actividades pasando datos con Intent putExtra
  • Consultar un registro de SQLite en Formulario

 

1: Diseño Layout Formulario

Creamos una nueva actividad HipotecaFormulario con diseño de formulario para mostrar los datos de cada registro en la tabla HIPOTECA de SQLite.
android_sqlite_formulario_ver_1

Editamos archivo res/layout/activity_hipoteca_formulario.xml dejándolo como sigue a continuación:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HipotecaFormulario" >

	<RelativeLayout
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:orientation="vertical"
	    android:padding="10dp" >

	    <TextView
	        android:id="@+id/label_nombre"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/label_nombre_hipoteca"
	        android:textAppearance="?android:attr/textAppearanceMedium" />
	
	    <EditText
	        android:id="@+id/nombre"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_nombre"
	        android:ems="10" />
	
	    <TextView
	        android:id="@+id/label_condiciones"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/label_condiciones"
	        android:textAppearance="?android:attr/textAppearanceMedium"
	        android:layout_below="@+id/nombre"
	        android:layout_marginTop="20dp" />
	    
	    <EditText
	        android:id="@+id/condiciones"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_condiciones"
	        android:ems="10"
	        android:inputType="textMultiLine">
	    </EditText>
	    
	    <TextView
	        android:id="@+id/label_contacto"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/label_contacto"
	        android:textAppearance="?android:attr/textAppearanceMedium"
	        android:layout_below="@+id/condiciones"
	        android:layout_marginTop="20dp" />
	    
	    <EditText
	        android:id="@+id/contacto"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_contacto"
	        android:ems="10">
	    </EditText>
	    
	    <TextView
	        android:id="@+id/label_telefono"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/label_telefono"
	        android:textAppearance="?android:attr/textAppearanceMedium"
	        android:layout_below="@+id/contacto"
	        android:layout_marginTop="20dp" />
	    
	    <EditText
	        android:id="@+id/telefono"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_telefono"
	        android:ems="10"
	        android:inputType="phone" >
	    </EditText>
	    
	    <TextView
	        android:id="@+id/label_email"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_below="@+id/telefono"
	        android:layout_marginTop="20dp"
	        android:text="@string/label_email"
	        android:textAppearance="?android:attr/textAppearanceMedium" />
	    
	   <EditText
	        android:id="@+id/email"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_email"
	        android:ems="10"
	        android:inputType="textEmailAddress"/>

    	<TextView
	        android:id="@+id/label_observaciones"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/label_observaciones"
	        android:textAppearance="?android:attr/textAppearanceMedium"
	        android:layout_below="@+id/email"
	        android:layout_marginTop="20dp" />
	    
	    <EditText
	        android:id="@+id/observaciones"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_alignParentLeft="true"
	        android:layout_below="@+id/label_observaciones"
	        android:ems="10"
	        android:inputType="textMultiLine">
	    </EditText>
	    
	</RelativeLayout>
</ScrollView>

Añadimos las etiquetas utilizadas en el formulario al archivo res/values/strings.xml

    <string name="label_nombre_hipoteca">Nombre:</string>
    <string name="label_condiciones">Condiciones:</string>
    <string name="label_contacto">Contacto:</string>
    <string name="label_telefono">Teléfono:</string>
    <string name="label_email">E-Mail:</string>
    <string name="label_observaciones">Observaciones:</string>

Diseño de layout_hipoteca_formulario.xml
android_sqlite_formulario_ver_2
 

2: Navegar a Activity Formulario desde la Activity principal

A continuación enlazamos la selección de cada uno de los registros de la lista de hipotecas con el formulario.
Para ello utilizaremos el evento onListItemClick de la ListActivity Hipoteca, que llama al método visualizar.Este método declara el Intent necesario para iniciar la nueva actividad. En este Intent incluimos los parámetros modo de comportamiento e identificador del registro seleccionado.

Hipoteca.java

package com.sodenet.hipotecas;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ListView;

public class Hipoteca extends ListActivity {

	public static final String C_MODO  = "modo" ;
	public static final int C_VISUALIZAR = 551 ;

	private HipotecaDbAdapter dbAdapter;
    private Cursor cursor;
    private HipotecaCursorAdapter hipotecaAdapter ;
    private ListView lista;

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

		lista = (ListView) findViewById(android.R.id.list);

		dbAdapter = new HipotecaDbAdapter(this);
		dbAdapter.abrir();

		consultar();
	}

	private void consultar()
	{
		cursor = dbAdapter.getCursor();
		startManagingCursor(cursor);
		hipotecaAdapter = new HipotecaCursorAdapter(this, cursor);
		lista.setAdapter(hipotecaAdapter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.hipoteca, menu);
		return true;
	}

	private void visualizar(long id)
	{
		// Llamamos a la Actividad HipotecaFormulario indicando el modo visualización y el identificador del registro
		Intent i = new Intent(Hipoteca.this, HipotecaFormulario.class);
		i.putExtra(C_MODO, C_VISUALIZAR);
		i.putExtra(HipotecaDbAdapter.C_COLUMNA_ID, id);

		startActivityForResult(i, C_VISUALIZAR);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id)
	{
		super.onListItemClick(l, v, position, id);

		visualizar(id);
	}
}

 

3: Consultar un Registro de SQLite

Desde la actividad Formulario recibiremos el identificador del registro que debe mostrarse, para obtener el registro de la base de datos SQLite incluiremos el nuevo método getRegistro en la clase HipotecaCursorAdapter.java.

package com.sodenet.hipotecas;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class HipotecaDbAdapter {

	/**
	 * Definimos constante con el nombre de la tabla
	 */
	public static final String C_TABLA = "HIPOTECA" ;

	/**
	 * Definimos constantes con el nombre de las columnas de la tabla
	 */
	public static final String C_COLUMNA_ID	= "_id";
	public static final String C_COLUMNA_NOMBRE = "hip_nombre";
	public static final String C_COLUMNA_CONDICIONES = "hip_condiciones";
	public static final String C_COLUMNA_CONTACTO = "hip_contacto";
	public static final String C_COLUMNA_EMAIL = "hip_email";
	public static final String C_COLUMNA_TELEFONO = "hip_telefono";
	public static final String C_COLUMNA_OBSERVACIONES = "hip_observaciones";

	private Context contexto;
	private HipotecaDbHelper dbHelper;
	private SQLiteDatabase db;

	/**
	 * Definimos lista de columnas de la tabla para utilizarla en las consultas a la base de datos
	 */
	private String[] columnas = new String[]{ C_COLUMNA_ID, C_COLUMNA_NOMBRE, C_COLUMNA_CONDICIONES, C_COLUMNA_CONTACTO, C_COLUMNA_EMAIL, C_COLUMNA_TELEFONO, C_COLUMNA_OBSERVACIONES} ;

	public HipotecaDbAdapter(Context context)
	{
		this.contexto = context;
	}

	public HipotecaDbAdapter abrir() throws SQLException
	{
		dbHelper = new HipotecaDbHelper(contexto);
		db = dbHelper.getWritableDatabase();
		return this;
	}

	public void cerrar()
	{
		dbHelper.close();
	}

	/**
	 * Devuelve cursor con todos los registros y columnas de la tabla
	 */
	public Cursor getCursor() throws SQLException
	{
		Cursor c = db.query( true, C_TABLA, columnas, null, null, null, null, null, null);

		return c;
	}

	/**
	 * Devuelve cursor con todos las columnas del registro
	 */
	public Cursor getRegistro(long id) throws SQLException
	{
		Cursor c = db.query( true, C_TABLA, columnas, C_COLUMNA_ID + "=" + id, null, null, null, null, null);

		//Nos movemos al primer registro de la consulta
		if (c != null) {
			c.moveToFirst();
		}
		return c;
	}
}

 

4: Mostrar registro en Activity Formulario

Una vez tenemos preparado el acceso desde la actividad principal al formulario y el adaptador para obtener el registro de la base de datos SQLite, modificamos la clase del formulario HipotecaFormulario.java como se detalla a continuación:

  • El método onCreate obtiene los datos que hemos pasado desde la Actividad principal
  • Preparamos el adaptador de base de datos que utilizaremos para consultar el registro
  • Obtenemos el registro de la base de datos y rellenamos los campos del formulario
  • Como hemos llamado al formulario en modo Visualización, desactivamos la edición de los campos
package com.sodenet.hipotecas;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.EditText;

public class HipotecaFormulario extends Activity {

	private HipotecaDbAdapter dbAdapter;
    private Cursor cursor;

	//
    // Modo del formulario
    //
	private int modo ;

	//
	// Identificador del registro que se edita cuando la opción es MODIFICAR
	//
	private long id ;

	//
	// Elementos de la vista
	//
	private EditText nombre;
	private EditText condiciones;
	private EditText contacto;
	private EditText telefono;
	private EditText email;
	private EditText observaciones;

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

		Intent intent = getIntent();
		Bundle extra = intent.getExtras();

		if (extra == null) return;

		//
		// Obtenemos los elementos de la vista
		//
		nombre = (EditText) findViewById(R.id.nombre);
		condiciones = (EditText) findViewById(R.id.condiciones);
		contacto = (EditText) findViewById(R.id.contacto);
		telefono = (EditText) findViewById(R.id.telefono);
		email = (EditText) findViewById(R.id.email);
		observaciones = (EditText) findViewById(R.id.observaciones);

		//
		// Creamos el adaptador
		//
		dbAdapter = new HipotecaDbAdapter(this);
		dbAdapter.abrir();

		//
		// Obtenemos el identificador del registro si viene indicado
		//
		if (extra.containsKey(HipotecaDbAdapter.C_COLUMNA_ID))
		{
			id = extra.getLong(HipotecaDbAdapter.C_COLUMNA_ID);
			consultar(id);
		}

		//
		// Establecemos el modo del formulario
		//
		establecerModo(extra.getInt(Hipoteca.C_MODO));

	}

	private void establecerModo(int m)
	{
		this.modo = m ;

		if (modo == Hipoteca.C_VISUALIZAR)
		{
			this.setTitle(nombre.getText().toString());
			this.setEdicion(false);
		}
	}

	private void consultar(long id)
	{
		//
		// Consultamos el centro por el identificador
		//
		cursor = dbAdapter.getRegistro(id);

		nombre.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_NOMBRE)));
		condiciones.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_CONDICIONES)));
		contacto.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_CONTACTO)));
		telefono.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_TELEFONO)));
		email.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_EMAIL)));
		observaciones.setText(cursor.getString(cursor.getColumnIndex(HipotecaDbAdapter.C_COLUMNA_OBSERVACIONES)));
	}

	private void setEdicion(boolean opcion)
	{
		nombre.setEnabled(opcion);
		condiciones.setEnabled(opcion);
		contacto.setEnabled(opcion);
		telefono.setEnabled(opcion);
		email.setEnabled(opcion);
		observaciones.setEnabled(opcion);
	}
}

 

5: Ejecución de la aplicación

Por el momento no tenemos posibilidad de editar los registros de nuestra tabla Hipotecas y todos los registros creados por defecto tienen únicamente el identificador y el nombre. Por tanto, para mostrar una información más completa en el formulario vamos a ampliar el contenido de registro con identificador 1.

Esto lo haremos desde el archivo HipotecaDbHelper.java. Modificamos la versión de la base de datos de 1 a 2 y en el método onUpgrade hacemos un UPDATE rellenando la información. Entraremos en detalle sobre esta cuestión en entradas posteriores.

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
	{
		if (newVersion == 2)
		{
			db.execSQL("UPDATE HIPOTECA SET hip_contacto = 'Julián Gómez Martínez'," +
		   			   "					hip_email = 'jgmartinez@gmail.com'," +
		   			   "					hip_observaciones = 'Tiene toda la documentación y está estudiando la solicitud. En breve llamará para informar de las condiciones'" +
		   			   " WHERE _id = 1");
		}

	}

¡Ya está todo listo! Ahora basta con ejecutar la aplicación en el emulador.

android_sqlite_formulario_ver_3


 
Si tienes alguna pregunta o algo que aportar no lo dudes … ¡tienes los comentarios a tu disposición!