Programación Android, Ejemplo de Bases de datos & ListView IV

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0

Android SQLite

En la última entrada nos quedamos a falta de lanzar una segunda Activity con los datos del ítem seleccionado del ListView, para poder modificarlos posteriormente. Con esta entrada terminaremos este ejemplo de como usar bases de datos en Android, con POO y MVC.

Implementar OnItemClickListener

En primer lugar vamos a implementar el Listener OnItemClickListener en la primera Activity, para que cuando suceda este evento recojamos la información del ítem seleccionado y lo enviemos a la segunda Activity. Añadiremos el Listener a la firma de nuestra Activity, y posteriormente escribiremos el método que nos pide:

public class MainActivity extends Activity implements OnClickListener, OnItemClickListener {
/* ... */

	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position,
			long id) {
		// TODO Añadir el código para recuperar la información y mandarla a la
		// segunda Activity.

	}
}

Recuperar datos del ítem del ListView

Ahora desarrollaremos el código que necesitamos para poder recuperar los datos del ítem que hemos seleccionado y enviárselo a la segunda Activity:

// Recogemos los datos a partir del Adapter. Aunque no hemos escrito el
// método getItem, este método ya está escrito en la clase ArrayAdapter,
// y nos devolverá el tipo de objeto que hemos declarado en la firma de
// nuestro Adapter (ArrayAdapter)
DatosTabla datos = adapterTabla2.getItem(position);

// Como al recoger los datos de la tabla también recogíamos el _id de la
// tupla, y ésta es la clave primaria, utilizaremos el _id para recoger
// en la segunda Activity los datos.
Bundle b = new Bundle();
b.putInt("ID", datos.get_id());

// Añadimos la información al Intent y lanzamos la segunda Activity.
// Ahora mismo nos dará error porque no existe la clase
// EditDataActivity.
Intent i = new Intent(this, EditDataActivity.class);
i.putExtras(b);

startActivity(i);

Crear la Activity para editar datos

Una vez que tenemos el envío de datos a la segunda Activity, vamos a crearla y a diseñar su Layout, que tendrá que contener tres EditText para mostrar nombre, apellido y teléfono, y un botón para confirmar la actualización de datos:

Layout EditData
EditDataActivity














    <button>


Mostrar datos en pantalla

Una vez que hemos diseñado el Layout vamos a añadir el código que necesitamos en nuestra Activity para recoger el _id que hemos mandado desde la Activity anterior, mostrar los datos en los EditText y que cuando se pulse el botón Actualizar se realice la actualización del registro en la base de datos. En primer lugar vamos a instanciar los EditText y escribir en ellos los datos actuales de la tabla:

private EditText etNombre, etApellido, etTelefono;
private int _id;

// Esta variable la utilizaremos más adelante en varios métodos
// por lo tanto la declaramos aquí.
private DatosTabla datos;

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

	etNombre = (EditText)findViewById(R.id.etNombre);
	etApellido = (EditText)findViewById(R.id.etApellido);
	etTelefono = (EditText)findViewById(R.id.etTelefono);

	// Recogemos el _id a partir del Intent.
	_id = getIntent().getExtras().getInt("ID");

	// Este paso dará error de compilación, porque el método
	// getDatosTabla2() que hemos creado no admite parámetros.
	datos = ((BDApplication)getApplication()).getDatosTabla2(_id);

	// Escribimos los datos en los EditText.
	etNombre.setText(datos.getNombre());
	etApellido.setText(datos.getApellido());
	etTelefono.setText(datos.getTelefono());

}

Crear las sobrecargas de los métodos

En este punto no existe el método getDatosTabla2(), en la clase BDApplication, que admita un objeto de tipo int como parámetro y devuelva un objeto de tipo DatosTabla. Recordemos que el método que habíamos hecho con el mismo nombre no recibía parámetros y devolvía un ArrayList con todos los datos de la tabla. Por lo tanto vamos a crear una sobrecarga del método, que admita un int como parámetro y devuelva un objeto DatosTabla:

/**
* Devuelve los datos de la tupla con el _id indicado.
* @param _id de la tupla de la tabla2
* @return DatosTabla con los datos de la tupla.
*/
public DatosTabla getDatosTabla2(int _id) {
		Cursor c = dbAdapter.getDatosTabla2(_id);
		return CursorToCollection.cursorToDatosTabla(c);
	}

A continuación crearemos la misma sobrecarga en la clase DBAdapter, pero que en su caso devolverá un objeto de la clase Cursor:

/**
* Devuelve los datos de la tupla con el _id indicado.
*
* @param _id
*            de la tupla de la tabla2
* @return Cursor con los datos de la tupla.
*/
public Cursor getDatosTabla2(int _id) {
	return tabla2.getDatos(_id);
}

El siguiente paso es crear la sobrecarga del método también en la clase Tabla2:

/**
* Devuelve los datos de la tupla con el _id indicado.
*
* @param _id
*            de la tupla de la tabla2
* @return Cursor con los datos de la tupla.
*/
public Cursor getDatos(int _id) {
	String selection = "_id=?";
	String[] selectionArgs = { String.valueOf(_id) };

	return sqlDB.query(NAME, COLUMNS, selection, selectionArgs, null, null,
			null);
}

Y sólo falta volver a la clase CursorToCollection para crear el método que recoja el cursor y devuelva los datos ya convertidos a DatosTabla:

/**
* Convierte un objeto Cursor a DatosTabla.
*
* @param c
*            Cursor con los datos de la tupla.
* @return DatosTabla con los datos que contenía el Cursor.
*/
public static DatosTabla cursorToDatosTabla(Cursor c) {
	DatosTabla datos;

	if (c.moveToFirst()) {
		// Recogemos los datos del cursor.
		int _id = c.getInt(c.getColumnIndex(Tabla2.Columns.ID));
		String nombre = c
				.getString(c.getColumnIndex(Tabla2.Columns.NOMBRE));
		String apellido = c.getString(c
				.getColumnIndex(Tabla2.Columns.APELLIDO));
		String telefono = c.getString(c
				.getColumnIndex(Tabla2.Columns.TELEFONO));

		datos = new DatosTabla(_id, nombre, apellido, telefono);
	} else {
		// Si el cursor no contenía datos creamos un objeto DatosTabla sin
		// datos.
		datos = new DatosTabla(0, "", "", "");
	}
	return datos;
}

Seleccionar el texto cuando el EditText gane el foco

Con estos cambios podremos ya ver los datos en los EditText, nos faltaría codificar la parte que nos permitirá actualizar la tabla con los datos nuevos. Primero vamos a hacer que cuando un EditText gane el foco (cuando se seleccione el control) quede todo el texto seleccionado, para que no sea necesario borrar y así se pueda escribir directamente el nuevo dato. Para ello en el xml de la vista añadimos la siguiente propiedad a los EditText:

android:selectAllOnFocus="true"

Actualizar datos de la Base de Datos

Lo último que nos falta por hacer es actualizar los datos cuando se pulsa el botón de Actualizar. Recordemos que en el xml de la vista hemos dicho que cuando se pulse el botón haga una llamada al método onClick(), por lo tanto vamos a codificarlo en nuestra Activity, y en él vamos a hacer la llamada al método de BDApplication que actualice los datos, después de comprobar que todos los EditText tienen texto escrito y que se ha modificado alguno de los datos:

public void onClick(View v) {
	String nombre = etNombre.getText().toString();
	String apellido = etApellido.getText().toString();
	String telefono = etTelefono.getText().toString();

	// Primero comprobamos si han cambiado los datos. Si no han cambiado
	// salimos de la Activity y no es necesario actualizar nada en la BD, de
	// lo contrario intentamos hacer la actualización.
	if (datos.getNombre() != nombre & datos.getApellido() != apellido
			& datos.getTelefono() != telefono) {
		DatosTabla datosTemp = new DatosTabla(_id, nombre, apellido,
				telefono);
		// Comprobamos que se actualiza correctamente.
		if (((BDApplication) getApplication()).updateTabla2(datosTemp)) {
			finish();
		} else {
			// Si no se ha actualizado correctamente la BD mostramos mensaje
			// de error en pantalla.
			showUpdateError();

		}
	} else {
		finish();
	}
}

/**
* Muestra en pantalla un mensaje de error de actualización de datos.
*/
public void showUpdateError() {
	Toast.makeText(this, "No se han actualizado los datos correctamente",
			Toast.LENGTH_SHORT).show();
}

Hecho esto, nos falta crear el método en la clase BDApplication que haga la llamada a DBAdapter que a su vez llamará al método de Tabla2 que actualice los datos:

    • En BDApplication:
/**
* Actualiza los datos de la tabla.
*
* @param datos
*            registro con los datos que se quieren actualizar.
* @return si se actualiza algún registro o no.
*/
public boolean updateTabla2(DatosTabla datos) {
	return dbAdapter.updateTabla2(datos);

}
    • En DBAdapter:
/**
* Actualiza los datos de una tupla de la tabla2.
*
* @param datos
*            que se quieren actualizar.
* @return si se actualiza algún registro o no.
*/
public boolean updateTabla2(DatosTabla datos) {
	return tabla2.updateTabla(datos);
}
    • En Tabla2:
/**
* Actualiza los datos de una tupla de la tabla.
*
* @param datos
*            que se quieren actualizar.
* @return si se actualiza algún registro o no.
*/
public boolean updateTabla(DatosTabla datos) {
	// Añadimos los nuevos datos a un objeto del tipo ContentValues.
	ContentValues values = new ContentValues();
	values.put(Columns.NOMBRE, datos.getNombre());
	values.put(Columns.APELLIDO, datos.getApellido());
	values.put(Columns.TELEFONO, datos.getTelefono());

	// Añadimos la clausula where y el valor que debe tener para actualizar
	// sólo el registro que contenga la _id que queremos.
	String whereClause = "_id=?";
	String[] whereArgs = { String.valueOf(datos.get_id()) };

	// Devolvemos si se han actualizado 1 o más registros.
	return sqlDB.update(NAME, values, whereClause, whereArgs) > 0;
}

Con esto ya hemos acabado de programar una aplicación que hace uso de una Base de Datos, con POO y utilizando el MVC de Android.

Descargas

Puedes ver el resultado del ejemplo en tu móvil descargando nuestra aplicación desde Google Play.

El proyecto completo puede descargarse aquí.

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
The following two tabs change content below.
Reborn as IT Developer. Desarrollador Android y fundador de Proyecto Simio. "En realidad, yo no puedo enseñar nada a nadie, sólo puedo hacerles pensar." - Sócrates.

9 thoughts on “Programación Android, Ejemplo de Bases de datos & ListView IV

  1. Hola muchas gracias por este hermoso ejercicio, por aplicar la arquitectura MVC en realidad hace más sencillo entender y modificar el código. Una duda: Después de hacer clic en el botón udpate si se modifica el registro en la tabla2 pero no se actualiza el ListView2. En donde debo hacer el llamado a update() del adaptador del segundo ListView para que refresque esta lista. Gracias de antemano :)

    1. Tengo intención de hacerlo en cuanto pueda, pero antes me gustaría hacer otros ejemplos sencillos para utilizar conexiones a Internet, y poco a poco aumentar la complejidad hasta crear la sincronización con la base de datos MySQL, con PHP y JSON como dices.

      Si necesitas ver ejemplos con urgencia envíanos un mail a proyectosimio@gmail.com y te mandaré algunos de los ejemplos más sencillos que tengo para que puedas echarles un vistazo ;)

      Un saludo, y gracias a ti por seguir el blog ^^

Deja un comentario