Cómo crear una lista personalizada en Android

Vamos a crear una lista personalizada en Android en la cuál sacaremos varios datos por pantalla a partir de un ArrayList de la clase que queramos modelar.

En nuestro ejemplo, mostraremos datos de una liga de fútbol. Para esto necesitamos crear:

item_list_liga.xml (Archivo xml con el diseño diseño de la lista)
PartidoLiga.java (Clase con los datos de la liga que nos interese mostrar)
PartidoLigaAdapter.java (Un adaptador al que le pasaremos los datos)
liga_activity_layout.xml (El diseño de la vista principal que cargará la lista)
LigaActivity.java (Clase principal que se ejecutará para mostrar los datos)

item_list_liga.xml

No voy a explicar cómo distribuir las vistas puesto que podéis hacerlo según vuestra preferencias, pero os muestro parte del esquema que he realizado. En este caso destacaría la forma de los puntos de clasificación, teniendo que crear el diseño en formato xml y guardarlo en la carpeta drawable de recursos:

<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
>
<solid android:color="#ECEFF1" />
<size
android:width="36dp"
android:height="36dp"
/>
<corners android:radius="18dp" />

</shape>

Para centrarlos de la vista y que no perdieran su forma, recurrí al uso del FrameLayout. El resultado es el siguiente:

En esta plantilla, los iconos de Android representan los logos de los equipos.

PartidoLiga.java

En esta clase identificamos los atributos que nos interese mostrar por pantalla, que serán los escudos de los equipos y sus nombres, las puntuaciones y los puntos de clasificación en la liga. Tras declarar las variables, inicializamos sus valores en el constructor:

public PartidoLiga(String jornada, int imagenEsc1, int imagenEsc2,
String nombreEquipo1, String nombreEquipo2, String goles1, String goles2,
String puntosClasificacion1, String puntosClasificacion2) {
this.jornada = jornada;
this.imagenEsc1 = imagenEsc1;
this.imagenEsc2 = imagenEsc2;
this.nombreEquipo1 = nombreEquipo1;
this.nombreEquipo2 = nombreEquipo2;
this.goles1 = goles1;
this.goles2 = goles2;
this.puntosClasificacion1 = puntosClasificacion1;
}

PartidoLigaAdapter.java

Esta clase hereda de ArrayAdater<PartidoLiga> por lo que debemos sobreescribir (override) el método getView. En este método inicializamos nuestra vista igual al parámetro de entrada convertView que, si es igual a null, la inflamos pasándole nuestra lista personalizada (item_list_liga):

View listaPersonalizada = convertView;

if(listaPersonalizada == null){
listaPersonalizada = LayoutInflater.from(getContext()).inflate(R.layout.item_list_liga, parent, false);
}

El siguiente paso es localizar el item dentro de nuestra lista, con el método getItem y el parámetro de entrada position:

PartidoLiga partidosLiga = getItem(position);

Ahora recuperamos nuestras vistas del archivo xml:

ImageView escudo1Iv = (ImageView) listaPersonalizada.findViewById(R.id.escudo1_image_view);
ImageView escudo2Iv = (ImageView) listaPersonalizada.findViewById(R.id.escudo2_image_view);
TextView nombreEquipo1Tv = (TextView) listaPersonalizada.findViewById(R.id.nombre_equipo1_text_view);
TextView nombreEquipo2Tv = (TextView) listaPersonalizada.findViewById(R.id.nombre_equipo2_text_view);
TextView goles1Tv = (TextView) listaPersonalizada.findViewById(R.id.goles1_text_view);
TextView goles2Tv = (TextView) listaPersonalizada.findViewById(R.id.goles2_text_view);
TextView puntos1Tv = (TextView) listaPersonalizada.findViewById(R.id.puntos1_text_view);
TextView puntos2Tv = (TextView) listaPersonalizada.findViewById(R.id.puntos2_text_view);

A los imageView le vamos asignar la imagen que le corresponda, pero si no tenemos imagen, ocultaremos la vista con Visibility.GONE. Para esto llamamos al método auxiliar declarado en PartidoLiga.java hasimage():

if(partidosLiga.hasImageEsc1()){
int escudo1 = partidosLiga.getImagenEsc1();
escudo1Iv.setImageResource(partidosLiga.getImagenEsc1());

// Como las view se reutilizan, tenemos que asegurar que estará visible
escudo1Iv.setVisibility(View.VISIBLE);
} else{
escudo1Iv.setVisibility(View.GONE);
}

if(partidosLiga.hasImageEsc2()){
int escudo2 = partidosLiga.getImagenEsc1();
escudo2Iv.setImageResource(partidosLiga.getImagenEsc2());

escudo1Iv.setVisibility(View.VISIBLE);
} else{
escudo2Iv.setVisibility(View.GONE);
}

Por último devolvemos nuestra lista personalizada, que ya se ha inflado y recuperado todas las vistas del xml, pasándole los datos correspondientes:

return listaPersonalizada;

liga_activity_layout.xml

Esta es la vista principal donde se mostrará la lista, por lo que debemos crear un ListView:

<ListView
android:id="@+id/liga_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawSelectorOnTop="true"
></ListView>

Iniciando el atributo drawSelectorOnTop a true, recibiremos feedback al pulsar sobre un item de la lista, con un efecto circular de fuera hacia dentro y respetando así la experiencia de usuario con Material Design.

LigaActivity.java

Ésta es la clase principal que va a mostrar los datos en la list view. Para esto, en el método onCreate declaramos los partidos que queramos mostrar, por ejemplo:

PartidoLiga partido1 = new PartidoLiga("1", R.drawable.ic_action_name, R.drawable.ic_action_name, 
"Real Madrid", "Portosín", "3", "1", "8", "3");
PartidoLiga partido2 = new PartidoLiga("1", R.drawable.ic_action_name, R.drawable.ic_action_name,
"Barcelona", "Sevilla", "2", "9", "15", "11");

Guardamos estos partidos en un arraylist:

ArrayList<PartidoLiga> listaPartidosLiga = new ArrayList<>();
listaPartidosLiga.add(partido1);
listaPartidosLiga.add(partido2);

Creamos nuestro Adapter pasándole el contexto y el arraylist creado:

PartidoLigaAdapter itemsListaLiga = new PartidoLigaAdapter(LigaActivity.this, listaPartidosLiga);

Localizamos la listView del activity principal:

ListView layoutLigaActivity = (ListView) findViewById(R.id.liga_list_view);

Pasamos a esta listView nuestro adaptador:

layoutLigaActivity.setAdapter(itemsListaLiga);

Al ejecutar veremos que nuestro arraylist se muestra en la lista por pantalla:

Lo interesante es que los datos se vayan actualizando de un servidor, pero esto ya quedará para otra entrada.


Show your support

Clapping shows how much you appreciated Manuel Mato’s story.