jueves, 22 de marzo de 2012

6.8.3.-P.Android-Puntuaciones III-Leyendo XML


6.8.3.- Programación en Android – Puntuaciones III -Leyendo XML

En este capítulo rellenaremos los datos de las tablas que hemos creado con los datos que hay en los ficheros XML con las puntuaciones ficticias. Veremos como añadir filas mediante TableRow a nuestro TableLayout, e igualmente cómo añadir objetos TextView al TableRow, para así poder componer la tabla.
Para cargar datos desde XML, la plataforma Android nos ofrece varias opciones:
    • SAX (Simple Api for Xml)
    • XML Pull Parser
    • Limited DOM con soporte de nivel 2.

El método que se desee utilizar dependerá del tipo de proyecto y en nuestro caso como sólo queremos leer el fichero XML para obtener los valores allí contenidos nos valdrá con utilizar el XML Pull Parser.
Para poder acceder a nuestros recursos XML de esta manera debemos utilizar el interfaz XMLResourceParser, que es un interfaz estándar de tipo XMLPullParser así como un interfaz extendido de AttributeSet así como un método adicional close() para que el cliente indique cuándo ha terminado de leer el recurso.
Visto esto crearemos dos instancias de este objeto, una para cada recurso XML de la siguiente manera:

Resources res = getResources();

//Creamos dos objetos de tipo XmlResourceParser
// uno para cada fichero de puntuación.
XmlResourceParser puntuacionesLocales = res
.getXml(R.xml.puntuacioneslocales);
XmlResourceParser puntuacionesGlobales = res
.getXml(R.xml.puntuacionesglobales);

Ahora lo que tenemos que hacer es sacar los datos de estos ficheros y añadirlos a nuestro TableLayout. Así que antes de crear el método para obtener los datos vamos a obtener las referencias a las vistas de los TableLayouts:

//Obtenemos las referencias a las vistas para rellenar
TableLayout tablaPuntuacionesLocales = (TableLayout) findViewById(R.id.tableLayout_PuntuacionesLocales);
TableLayout tablaPuntuacionesGlobales = (TableLayout) findViewById(R.id.tableLayout_PuntuacionesGlobales);

Ahora podemos crear el método para obtener los datos y asignarlos a estas tablas. Las llamadas al método serían de la siguiente manera:

try
{
//Cargamos los datos de las tablas
cargaPuntuacionesXML(tablaPuntuacionesLocales, puntuacionesLocales);
cargaPuntuacionesXML(tablaPuntuacionesGlobales,
puntuacionesGlobales);
}
catch (Exception e)
{
//Con uno llegaría, pero como este desaparece al cambiar el valor de debug...
if (VALOR_DEBUG) Log.e(LOG_GLOBAL,
"Excepción: En cargaPuntuacionesXML " + e);

Log.e(LOG_GLOBAL, "Excepción: En cargaPuntuacionesXML: " + e);
}

Como veis se ha puesto dentro de un bloque try{...}catch{...} ya que se puede producir alguna excepción al cargar los recursos.

Añadiremos ahora el siguiente método, encargado de cargarlas puntuaciones en XML:

/**
* Método encargado de cargar las puntuaciones de los
* ficheros XML. También añade estas puntuaciones a
* las tablas.
* @param tablaPuntuaciones:Tabla a rellenar
* @param puntuaciones:Objeto XmlResourceParser del fichero XML
* @throws XmlPullParserException, IOException
*/
private void cargaPuntuacionesXML(TableLayout tablaPuntuaciones,
XmlResourceParser puntuaciones) throws XmlPullParserException,
IOException
{
int iTipoDeEvento = -1;
//Esta variable indica si se encontraron o no ficheros de puntuaciones.
boolean bExistenPuntuaciones = false;

//Bucle hasta el fin del documento:
while (iTipoDeEvento != XmlResourceParser.END_DOCUMENT) //Hay que acceder de forma estática (no con puntuaciones.END_DOCUMENT
{
//Comprobamos si se ha encontrado una etiqueta:
if (iTipoDeEvento == XmlResourceParser.START_TAG)
{
//Se ha encontrado una etiqueta, miramos si es
// alguna de las nuestras:
// (puntuaciones, puntuacion (jugador,puntos,posicion)
String strEtiqueta = puntuaciones.getName();
if (strEtiqueta.equals("puntuacion"))
{
//Indicamos que SI existen puntuaciones:
bExistenPuntuaciones = true;
//FIXME: Formatear las cadenas antes de añadirlas al textview.
//Cargamos los datos de esta entrada:
String strNombreJugador = puntuaciones.getAttributeValue(
null, "jugador");
String strPuntos = puntuaciones.getAttributeValue(null,
"puntos");
String strPosicion = puntuaciones.getAttributeValue(null,
"posicion");
//Añadimos esta fila de puntuaciones a la tabla:
//TODO: Añadirlo a un array. Y después actualizar desde el array.
//TODO: Hacer un ordenado de la tabla, en caso de estar desordenada.
añadeFilaPuntuaciones(tablaPuntuaciones, strNombreJugador,
strPuntos, strPosicion);

}
}
//Obtenemos el siguiente elemento del fichero xml:
iTipoDeEvento = puntuaciones.next();
}
//En caso de no haber puntuaciones, ponemos otro texto
// en la tabla:
if (bExistenPuntuaciones == false)
{
Resources res = getResources(); //Objeto para acceder a los recursos

final TableRow fila = new TableRow(this);
final TextView sinPuntuaciones = new TextView(this);
//Configuramos el texto del textview:
sinPuntuaciones.setText(res.getString(R.string.strSinPuntuaciones));
//Configuramos el color del texto del textView:
sinPuntuaciones.setTextColor(res
.getColor(R.color.color_Texto_Puntuaciones));
//Configuramos el tamaño del texto del textview:
sinPuntuaciones.setTextSize(res
.getDimension(R.dimen.dim_Texto_Puntuaciones));
//Añadimos el texto a la fila (TableRow):
fila.addView(sinPuntuaciones);
//Añadimos la fila a la tabla (TableLayout):
tablaPuntuaciones.addView(fila);
}
}

Como podéis ver en la cabecera del método hay un throws que indica que puede producir una excepción, y que ésta debe ser manejada fuera, ya que no se controla dentro del método.
También se observa que tenemos una llamada a un método auxiliar “añadeFilaPuntuaciones”, que se encarga de añadir un TableRow al tableLayout.
Esté método, así como otro auxiliar empleado por este quedarían de la siguiente manera:

/**
* Método auxiliar de cargaPuntuacionesXml(...) para
* insertar los valores en una fila de la tabla.
* @param tablaPuntuaciones: (TableLayout) de la tabla a añadir la fila
* @param strNombreJugador: Texto con el nombre del jugador
* @param strPuntos : Texto con la puntuación.
* @param strPosicion: Texto con la posición en el ranking.
*/
private void añadeFilaPuntuaciones(TableLayout tablaPuntuaciones,
String strNombreJugador, String strPuntos, String strPosicion)
{
//tablaPuntuaciones.inflate(context, resource, root);
Resources res = getResources();
//Creamos un objeto TableRow nuevo:
final TableRow fila = new TableRow(this);
//Configuración del color del texto:
int colorTexto = res.getColor(R.color.color_Texto_Puntuaciones);
//Configuración del tamaño del texto:
float tamañoTexto = res.getDimension(R.dimen.dim_Texto_Puntuaciones);
//Añadimos el texto con su configuración a la fila
añadeTextoAFilaTabla(fila, strPosicion, colorTexto, tamañoTexto);
añadeTextoAFilaTabla(fila, strNombreJugador, colorTexto, tamañoTexto);
añadeTextoAFilaTabla(fila, strPuntos, colorTexto, tamañoTexto);

//Y por último añadimos la fila a nuestra tabla:
tablaPuntuaciones.addView(fila);
}

/**
* Método auxiliar para añadeFilaPuntuaciones
* Añade una fila a la tabla de puntuaciones.
* @param fila: TableRow a la que añadir el texto.
* @param strNombreJugador: Texto con el nombre del jugador.
* @param colorTexto: Color del texto
* @param tamañoTexto: Tamaño del Texto.
*/
private void añadeTextoAFilaTabla(final TableRow fila,
String strNombreJugador, int colorTexto, float tamañoTexto)
{

//Creamos un objeto TextView:
TextView vistaTexto = new TextView(this);
//Configuramos el Texto de Este TextView:
vistaTexto.setTextColor(colorTexto);
//Configuramos el tamaño del texto:
vistaTexto.setTextSize(tamañoTexto);
//Y configuramos el texto:
vistaTexto.setText(strNombreJugador);
//Y finalmente lo añadimos a nuestra fila:
fila.addView(vistaTexto);

}

Al llegar a este punto sólo nos falta añadir la cabecera de la tabla, y el método empleado es el siguiente:

/**
* Método para añadir la cabecera a la tabla indicada.
* Los parámetros de color y de tamaño se cogen de los
* recursos.
* @param tablaPuntuacionesLocales
*/
private void añadeCabeceraTabla(TableLayout tabla)
{
Resources res = getResources();
//Obtenemos el color para la cabecera:
int iColor = res.getColor(R.color.color_Texto_Cabecera_Puntuaciones);
//Obtenemos el tamaño del texto de la cabecera:
float fTamañoTexto = res.getDimension(R.dimen.dim_Texto_Puntuaciones);
//Creamos un objeto TableRow para añadir los TextViews de la cabecera:
TableRow cabeceraTabla = new TableRow(this);
//Creamos las views (textViews) que tendrán la cabecera:
añadeTextoAFilaTabla(cabeceraTabla,
res.getString(R.string.strPosicion), iColor, fTamañoTexto);
añadeTextoAFilaTabla(cabeceraTabla,
res.getString(R.string.strNombreJugador), iColor, fTamañoTexto);
añadeTextoAFilaTabla(cabeceraTabla,
res.getString(R.string.strPuntuacion), iColor, fTamañoTexto);

/**
* Añadimos la vista:
* El 0 indica la posición donde se inserta la vista.
* Puede ser cualquiera, siempre que exista.
* Si la tabla no tiene ningún elemento y se pone >0,
* entonces provoca una excepción.
*/
tabla.addView(cabeceraTabla, 0);

}

A este método lo podemos llamar antes o después de rellenar la tabla. Ya que utilizamos el método addView junto con un índice en el que situar la cabecera.

Y ya podemos ejecutar nuestra aplicación. Faltan algunas pequeñas correcciones y optimizaciones que serán realizadas en próximos capítulos.
Hasta el próximo tutorial...


Ver. 1.0 – Revisión 21/03/2012

No hay comentarios:

Publicar un comentario