Jugando con Listas (I)

Vamos a hacer una app muy sencilla que mostrará el funcionamiento de las ListView. En el layout tendrá una un EditText para introducir nuevos elementos a la lista, un botón (Button) para pasar el elemento nuevo del EditText a la lista propiamente dicha y un ListView que será nuestra lista. Los valores de cadenas de texto y colores los mantendremos en sus respectivos ficheros strings.xml y colors.xml dentro de la carpeta /res/values. Parecerá mas engorroso, pero a la larga será lo mejor.

Empezaremos creando el proyecto. Ya vimos cómo hacerlo, así que sólo señalaré el nombre ListaTonta1, el target 2.2, el nombre del paquete com.alberovalley.listatonta1, y el nombre de la actividad a crear Principal.

Con todo listo, nos iremos al fichero de layout /res/layout/main.xml y haremos las modificaciones necesarias. Eliminamos el TextView que viene por defecto, metemos otro LinearLayout orientado en horizontal para que contenga el EditText y el Button, y debajo de este layout metemos el ListView. El resultado debería ser algo parecido a esto:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/fondo_layout_principal"
    >
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	    android:orientation="horizontal"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:background="@color/fondo_layout_secundario"
	    android:weightSum="1"
	    android:padding="5dp"
	    >
		<EditText android:id="@+id/entrada"
			android:layout_width="fill_parent"
	    	android:layout_height="wrap_content"
	    	android:hint="@string/hint"
	    	android:layout_weight="0.3"
		/>
		<Button android:id="@+id/boton"
			android:layout_width="fill_parent"
	    	android:layout_height="wrap_content"
	    	android:text="@string/boton"
	    	android:layout_weight="0.7"
		/>
	</LinearLayout>
	<ListView android:id="@+id/lista"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
	/>
</LinearLayout>

Aquí estamos practicando varias cosas nuevas a la vez. La primera, a meter un layout dentro de otro. Esto suele ser muy habitual a la hora de diseñar interfaces. Personalmente diré que para mi puede resultar mas difícil hacer que la interfaz se parezca a lo que quiero que lograr que el código haga lo que espero que haga. Para los acostumbrados a maquetar en html, sin embargo, debería resultar mas sencillo ya que los c onceptos empleados derivan de allí. Pero volvamos a lo nuestro.

Tenemos un LinearLayout horizontal dentro de uno vertical. El externo o raíz (el vertical) ocupa las dos dimensiones al máximo (fill_parent), mientras que el interno u horizontal sólo ocupa totalmente la dimensión horizontal, dejando que la vertical ocupe sólo lo que precise su contenido (wrap_content). Además de eso, tenemos la ListView, que ocupará todo el espacio que quede en su layout padre, que viene a ser toda la pantalla salvo la parte ocupada por el interno. Le añado colores al fondo de los layouts porque ayuda mucho a la hora de ir maquetando ver qué espacio van ocupando cada cosa. Al layout interno le damos un weightSum de 1. Eso quiere decir que el espacio a repartirse entre sus elementos contenidos (en este caso la caja de texto y el botón) se hará en función de la unidad. El atributo a usar para ello tanto en el botón como en la caja de texto es android:layout_weight, el cual funciona de un modo peculiar. Si de un valor X tú quieres que un elemento ocupe el Y%, debes asignarle a ese elemento el layout_weight=(X-Y). En el código podemos ver que la caja de texto tiene un layout_weight de 0.3 frente a los 0.7 del botón, pero pese a ello la caja de texto ocupa aproximadamente el 70% del espacio horizontal.

El ListView, que nunca se puede ver hasta que tenga datos que mostrar, lo fijamos debajo (esto es, fuera) del layout horizontal.

En el fichero /res/values/strings.xml añadimos dos cadenas mas: la del texto del botón y la del hint del EditText, quedando como sigue. Yo he eliminado la string hello por no necesitarla (sólo se usaba para el TextView que hemos eliminado).

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hint">Nuevo Elemento</string>
    <string name="boton">Intro</string>
    <string name="app_name">ListaTonta1</string>
</resources>

Los colores los pongo para que podamos ver con mas facilidad cómo quedan los diferentes LinearLayout uno dentro del otro. Para crear los colores, debemos hacer click derecho en la carpeta values, New -> Android XML File y ahí marcar si no lo estaba la opción values y nombrarlo como colors.xml. Su contenido será:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="fondo_layout_principal">#55009999</color>
    <color name="fondo_layout_secundario">#55009900</color>

</resources>

Apariencia de la interfaz
Se pueden observar los dos tonos de verde. El mas oscuro pertenece al LinearLayout raiz, el que contiene todo lo demás. Ocupa toda la pantalla a lo alto y ancho. Dentro hemos puesto otro LinearLayout (fondo verde claro, orientado en horizontal y ocupando lo necesario en vertical pero todo lo horizontal posible) para contener el botón y la caja de texto. La lista no se verá hasta que tenga elementos.

Pasemos al código Java de la actividad Principal.

package com.alberovalley.listatonta1;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class PrincipalActivity extends Activity implements OnClickListener {

	private ListView lista;
	private EditText entrada;
	private Button boton;
	private ArrayAdapter<String> adaptador;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lista = (ListView)findViewById(R.id.lista);
        entrada = (EditText)findViewById(R.id.entrada);
        boton = (Button)findViewById(R.id.boton);
        boton.setOnClickListener(this);
        adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
        lista.setAdapter(adaptador);
    }

	public void onClick(View v) {
		if(v.getId() == R.id.boton){
			String entrado = entrada.getText().toString();
			if (!entrado.equalsIgnoreCase("")){
				adaptador.add(entrado);
				entrada.setText("");
			}
		}

	}
}

Primero, le damos atributos privados a la clase: uno por cada elemento de interfaz que queramos manipular mas un ArrayAdapter del que hablaremos más adelante. En el método onCreate, como siempre, asociamos los atributos a sus respectivos elementos de interfaz a través del findViewById. Al botón le indicamos que su Listener para el evento onClick será la propia actividad. Como ya viéramos antes, eso implica que la actividad tiene que implementar la interfaz OnClickListener y, por tanto, el método onClick(View v). Lo dejamos todo listo. Al atributo que asociamos a la vista tenemos que darle un adaptador. Los adaptadores son objetos que se encargan de pasarle los datos a la lista e indicarle cómo mostrarlos. Cómo esta lista va a contener cadenas de texto simple en cada elemento, usamos el ArrayAdapter, que es muy sencillo. Para instanciarlo sólo se precisa pasarle el contexto (la propia actividad, ya que Activity hereda de Context, es un contexto) y el layout del elemento de lista, que por ser algo tan sencillo usaremos uno que trae Android por defecto y cuyo identificador es android.R.simple_list_item_1. Noten que en vez de llamar a “nuestra” R, nuestra clase generada con los IDs que vamos creando, se llama a una R de android. Si quisieramos que nuestra lista sacara los elementos de algún modo especial (color, formato de texto, etc), sí deberíamos crear nuestro propio layout para el list_item y pasárselo al instanciar el adaptador. Con el adaptador instanciado, se lo pasamos a la lista con setAdapter(adaptador). Pasamos al método onClick. Comprobamos que el evento lo dispara el botón comparando el id del viLista con elementosew que llama al método con el de nuestro botón. De ser cierto, confirmamos si hay algo escrito en la caja de texto asegurándonos que no sea una cadena vacía “”. De ser así, metemos el texto que sea en el ArrayAdapter (para poder usarlo fuera del onCreate era necesario que fuese un atributo de la clase) con adaptador.add(cadena) y borramos la caja de texto para que pueda volverse a usar sin problemas. Por supuesto, lo que introduzcamos en la lista desaparecerá entre una ejecución de la app y la siguiente, dado que no hay persistencia de datos alguna, pero como ejercicio para empezar a entender las listas servirá. Así quedaría la lista en plena ejecución, con algunos elementos ya introducidos:

El código completo de esta app puede encontrarse en el repositorio correspondiente de github

Anuncios

2 comentarios to “Jugando con Listas (I)”

  1. Hola, me podrías ayudar con cambiar el color del texto de una listView, porfavor que ya he buscado mucho y no encuentro nada.. lo que quiero conseguir es tener el fondo del layout negro (eso ya lo tengo) y que los textos de la textView sean blancas.
    Gracias!
    éste es el layout donde se encuentra la listView.

    • Depende de cómo sean tus listItems. Si es una lista compleja (varios textViews por item de la lista), habrás creado un layout de listItem: ahí es dónde deberías tocar para que siempre salgan en blanco 😉

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: