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

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

Android SQLite

En la anterior publicación sobre el manejo de bases de datos nos quedamos en el punto en el que teníamos que recoger los datos de la BD para mostrarlos en el primer ListView.

Creando la clase Modelo

Para hacer esto en primer lugar vamos a crear una nueva clase, que actuará de Modelo de datos, es decir, será una clase que va a representar la estructura de la tabla a la que queremos acceder, de manera que los datos de cada tupla de la tabla se almacenarán en un objeto de la clase Modelo creada:

/**
 * Clase Modelo de las tablas de la BD.
 *
 * @author ProyectoSimio
 *
 */
public class DatosTabla {
	private int _id;
	private String nombre, apellido, telefono;

	/**
	 * Constructor de la clase Modelo para las tablas de la BD
	 *
	 * @param _id
	 * @param nombre
	 * @param apellido
	 * @param telefono
	 */
	public DatosTabla(int _id, String nombre, String apellido, String telefono) {
		this._id = _id;
		this.nombre = nombre;
		this.apellido = apellido;
		this.telefono = telefono;
	}

	// Getters & setters:
	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public String getApellido() {
		return apellido;
	}

	public void setApellido(String apellido) {
		this.apellido = apellido;
	}

	public String getTelefono() {
		return telefono;
	}

	public void setTelefono(String telefono) {
		this.telefono = telefono;
	}

	// El campo _id es la clave primaria que no tiene sentido modificar, por lo
	// tanto no le creamos un set a este campo.
	public int get_id() {
		return _id;
	}

}

Mostrar los datos en el ListView

Una vez que hemos creado la clase, que no vamos a utilizar ahora mismo, pero sí se usará a la hora de utilizar el 2º ListView, recordemos que ya teníamos un método que nos devolvía un objeto Cursor que contenía todos los nombres de las tuplas que habíamos insertado previamente. Llegados a este punto, muchos autores deciden tratar los datos en el mismo método que recoge los datos de la tabla, y devolver, por ejemplo, un ArrayList con los datos que necesitan. Sin embargo, personalmente considero que la clase que controla el acceso a la tabla no tiene por qué saber tratar los datos, sino que eso se tiene que hacer a un nivel superior, desde una clase que se encargue de controlar estos datos, de manera que la clase que accede a la tabla sólo sabrá acceder a la tabla y devolver el resultado sin tratarlo (el Cursor). Para tratar los datos considero que la mejor opción es hacerlo desde nuestra clase Application, que no deja de ser una clase que se dedica a controlar toda la actividad de nuestra aplicación, y a través de la que pasan todos los datos. Implementando esta solución paso por paso, en primer lugar iremos a nuestra Activity y empezaremos a crear el código para utilizar nuestro ListView. Para el primero de los ListView vamos a utilizar un ArrayAdapter al que le pasaremos los nombres que hayan guardados en la tabla:

public class MainActivity extends Activity {
	private ListView lvTabla1;
	private ArrayList nombres;

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

		// Recogemos los nombres.
		nombres = ((BDApplication) getApplication()).getNombresTabla1();

		// Creamos un Adapter y le pasamos la lista de nombres.
		ArrayAdapter adapter = new ArrayAdapter(this,
			    android.R.layout.simple_list_item_1, nombres);

		// Inicializamos el ListView y le asignamos el Adapter.
		lvTabla1 = (ListView) findViewById(R.id.lvTabla1);
		lvTabla1.setAdapter(adapter);
	}
}

Crear la colección de datos

Sin embargo nuestra clase Application no contiene el método getNombresTabla1(), por lo tanto vamos a crearlo:

/**
 * Recoge los nombres almacenados en la tabla1 de la BD.
 *
 * @return ArrayList
 */
public ArrayList getNombresTabla1() {
	Cursor c = dbAdapter.getNombresTabla1Cursor();
	return null;
}

De momento en este método dejamos que devuelva null, primero vamos a crear el método con el que podremos recoger el Cursor con los datos de la tabla en la clase DBAdapter:

/**
 * Lee los nombres de la tabla1 de la BD
 * @return Cursor
 */
public Cursor getNombresTabla1Cursor() {
	return tabla1.getNombres();
}

El método getNombres() de Tabla1 ya lo teníamos creado previamente, por lo tanto lo que nos queda es tratar el Cursor en Application para convertirlo en el ArrayList que contenga los nombres para poder usarlo en nuestro Adapter. En este punto vamos a crear una nueva clase, que será la que se va a encargar de recoger los cursores y tratarlos para convertirlos en las colecciones que necesitemos. Esto lo realizamos así por el mismo motivo que dijimos que la tabla no debía tratar esos datos. En este caso Application es la clase que se encarga de gestionar y controlar toda la aplicación, pero su función no va más allá, por lo tanto para tratar los datos crearemos otra clase que lo haga, y desde Application la usaremos:

/**
 * Clase con métodos estáticos que tratan los cursores de la BD para
 * convertirlos en colecciones de datos.
 *
 * @author ProyectoSimio
 *
 */
public class CursorToCollection {

	/**
	 * Convierte un objeto Cursor en un ArrayList con los nombres.
	 *
	 * @param c
	 * @return ArrayList
	 */
	public static ArrayList cursorToArrayNombres(Cursor c) {
		ArrayList nombres = new ArrayList();

		// Si el cursor contiene datos los añadimos al ArrayList
		if (c.moveToFirst()) {
			do {
				nombres.add(c.getString(0));
			} while (c.moveToNext());
		}

		return nombres;
	}
}

Ahora completamos el método que dejamos a medias en Application:

/**
 * Recoge los nombres almacenados en la tabla1 de la BD.
 *
 * @return ArrayList
 */
public ArrayList getNombresTabla1() {
	Cursor c = dbAdapter.getNombresTabla1Cursor();
	return CursorToCollection.cursorToArrayNombres(c);
}

Y ya tendremos totalmente operativo el primero de los ListView:

Activity Principal
Activity Principal

Copiar los datos de una tabla en la otra

A continuación vamos a habilitar el botón para copiar los datos de la primera tabla en la segunda. La forma en que vamos a hacerlo es implementando el interface onClickListener en la firma de la clase de la Activity principal, y posteriormente desarrollando el método onClick() en la clase, y dentro del método haremos la llamada a un método de Application para copiar los datos de una tabla a otra:

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

	@Override
	public void onClick(View v) {
		((BDApplication)getApplication()).copiarTabla1ATabla2();
	}
}

El método lo crearemos en la clase Application, y hará la llamada al método de la clase DBAdapter, que se encargará de hacer la copia de datos de una tabla a otra.

  • En la clase Application:
/**
 * Copia los datos de la tabla1 a la tabla2.
 */
public void copiarTabla1ATabla2() {
	dbAdapter.copiarTabla1ATabla2();
}
  • En la clase DBAdapter:
/**
 * Inserta en la tabla2 todos los datos de la tabla1.
 */
public void copiarTabla1ATabla2() {
	Cursor c = tabla1.getDatos();
	tabla2.insertDatos(c);
}

A continuación crearemos dos métodos. Uno getDatos() en la clase Tabla1, que devolverá un Cursor con todos los datos de la tabla, el otro insertDatos() en la clase Tabla2, que recorrerá el cursor que recibe e introducirá todos los datos en la tabla.

  • En la clase Tabla1:
/**
 * Devuelve todos los datos que contiene la tabla.
 *
 * @return Cursor
 */
public Cursor getDatos() {
	return sqlDB.query(NAME, COLUMNS, null, null, null, null, null);
}
  • En la clase Tabla2:
/**
 * Recorre el cursor con los datos de la tabla1 para insertarlos en la
 * tabla2.
 *
 * @param c
 */
public void insertDatos(Cursor c) {
	if (c.moveToFirst()) {
		do {
			// Recogemos los datos del cursor. Como el cursor tiene varios
			// campos, y no tenemos por qué saber el orden en que están en
			// el cursor, lo que hacemos es recoger el índice que ocupa cada
			// campo a través del método getColumnIndex() del cursor, y le
			// pasamos el nombre del campo recogiéndolo de la clase Tabla1.
			String nombre = c.getString(c
					.getColumnIndex(Tabla1.Columns.NOMBRE));
			String apellido = c.getString(c
					.getColumnIndex(Tabla1.Columns.APELLIDO));
			String telefono = c.getString(c
					.getColumnIndex(Tabla1.Columns.TELEFONO));

			insert(nombre, apellido, telefono);
		} while (c.moveToNext());
	}
}

Por último volveremos a la Activity principal, para instanciar e inicializar el botón y posteriormente implementarle el Listener onClickListener:

Button btCopiar;

@Override
protected void onCreate(Bundle savedInstanceState) {
	/* ... */

	btCopiar = (Button)findViewById(R.id.btnCopiar);
	btCopiar.setOnClickListener(this);
}

En la próxima entrada mostraremos todos los datos de la segunda tabla en el ListView, con un Adapter personalizado para mostrar los 3 campos de la tabla.

Descargas

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

El código que llevamos realizado hasta el momento 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.

10 thoughts on “Programación Android, Ejemplo de Bases de datos & ListView II

  1. Hola, primeramente gracias por compartir tus conocimientos, son pocos los ejemplos que se ven en la Web usando el modelo MVC, muchas gracias nuevamente.

    Tengo una pregunta, en el objeto DatosTabla, existen métodos “get” y “set”, cómo los puedo usar para buscar un determinado valor ?, es decir, quiero buscar el ID = 10 y que de este registro me devuelva su nombre.

    Gracias & Saludos.

  2. hola, se hago una consulta: como mostrar en el ListView varios datos de una tabla, por ejemplo la tabla PERSONA que tiene los campos NOMBRE, EDAD, SEXO y mostrar los tres datos en el listview por cada persona… cuando realizo la consulta con el metodo “query” o “rawquery” me devuelve un solo campo.. espero que se entieda y muchas gracias por tu ayuda, muy buen blog. Saludos

      1. hola amigo mi nombre es anibal del tec de comitancillo tengo unos programas que entregar, abria forma que me diera unos tips o ejemplos??

  3. Te hago una consulta, como hacer para importar una base de datos creada con sql manager (es un archivo .sqlite) a un proyecto android y leer los datos desde ahi. muchas gracias

    1. Buenas, el código sería algo así:

      File dbfile = new File("/sdcard/mydb.sqlite" ); 
      SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
      System.out.println("Its open? "  + db.isOpen());
      

      Cambia la ruta por la tuya y solucionado.

      Un saludo.

Deja un comentario