Cómo añadir iconos a un ListView en Android

In: Android|Tutoriales

3 ago 2009

Hace poco añadimos un enlace a una gran cantidad de imágenes e iconos para incluir en los Proyectos de Android. Pues bien, ya va siendo hora de darles utilidad. Vamos a añadir un icono a un ListView, de ésta manera tendremos un diseño mucho más agradable e añadiremos alguna funcionalidad extra. [tweetmeme]

¿Qué es esto?

En éste tutorial vamos a añadir un icono a cada línea de un ListView.

¿Qué voy a aprender?

  • Acceder a las propiedades de un control desde código.
  • Caputarar los eventos de un ListView.
  • Crear nuevas clases y utilizarlas en la aplicación.

¿Cómo quedará?

screenshot1


Pasos a seguir:

Para simplificar el tutorial crearemos un nuevo Proyecto de Android que creará el ListView y lo poblará con iconos y textos. De ésta manera será mucho más fácil añadirlo a otros proyectos sin invertir mucho tiempo en la tarea.

Lo primero que vamos a hacer es crear el diseño de nuestra aplicación. Se trata de un XML muy simple donde añadiremos un ListView.

main.xml:


< ?xml version="1.0" encoding="utf-8"?>

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/settings"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<listview android:id="@+id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

</linearlayout>

Un ListView, por defecto, sólo permite añadir líneas de texto. Cabe destacar que si el número de elementos es mayor del que podemos ver en pantalla él solito se encarga de hacer un Scroll cuando movamos naveguemos por la pantalla, así que no hace falta crear un Scroller,ya que el control es automático. Para poder añadir un icono vamos a tener que crear un nuevo Layout que corresponderá a la nueva línea que veremos en el ListView.

IconRow.xml:


<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">

<imageview android:id="@+id/icon"

android:layout_width="wrap_content"
android:layout_height="fill_parent"

android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="6dip"/>

<textview android:id="@+id/row_toptext"

android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:layout_toRightOf="@id/icon"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"

android:singleLine="true"
android:ellipsize="marquee"/>

</relativelayout>

Ahora que ya hemos creado todos los Layouts necesarios ya podemos empezar a escribir código. Lo primero que vamos a hacer es crear una nueva clase llamada Local, cada línea del ListView contendrá un elemento de ésta clase.

Local.java:


package com.mobiledev;

public class Local {

private String localName;
private int localImage;

public String getLocalName() {
return localName;
}
public void setLocalName(String localName) {
this.localName = localName;
}
public int getLocalImage() {
return localImage;
}
public void setLocalImage(int i) {
this.localImage = i;
}

}

Ya tenemos el contenido, lo siguiente que necesitamos es un Adapter que se encargue de pasar la información de cada elemento de la clase al ListView.

IconListViewAdapter: (dentro de IconListView.java)


public class IconListViewAdapter extends ArrayAdapter<local> {

private ArrayList</local><local> items;

public IconListViewAdapter(Context context, int textViewResourceId, ArrayList</local><local> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.iconrow, null);
}
Local o = items.get(position);
if (o != null) {

//poblamos la lista de elementos

TextView tt = (TextView) v.findViewById(R.id.row_toptext);
ImageView im = (ImageView) v.findViewById(R.id.icon);

if (im!= null) {
im.setImageResource(o.getLocalImage());
}
if (tt != null) {
tt.setText(o.getLocalName());
}
}
return v;
}
}

Como veis el Adapter se encarga de coger los datos que le vamos pasando y colocarlos en el ListView. Utilizando los métodos findviewbyId lo que conseguimos es acceder a los compoenentes de la fila y pasarle los datos que queramos. Por último sólo falta el código fuente de la aplicación, donde en un métido a parte nos encargaremos de indicar el texto y las imágenes que queremos añadir.

Éste proceso se debe hacer dentro del método onCreate de la aplicación principal, de ésta manera sólo lo haremos una vez y estará disponible durante todo el LifeCycle.

IconListView.java:


package com.mobiledev;

import java.util.ArrayList;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class IconListView extends ListActivity {
private ArrayList</local><local> m_locals = null;
private IconListViewAdapter m_adapter;

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

/*
* Al crear la clase se inicializa el ListView que muestra los men�s
*/

m_locals = new ArrayList</local><local>();
this.m_adapter = new IconListViewAdapter(this, R.layout.iconrow, m_locals);
setListAdapter(this.m_adapter);

inicializarLocales();

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Local local = (Local) l.getItemAtPosition(position);

Toast.makeText(this, local.getLocalName(),
Toast.LENGTH_LONG).show();
}

/*
* Inicializacion del mapa
*/

private void inicializarLocales(){

try {
m_locals = new ArrayList</local><local>();
Local o1 = new Local();
o1.setLocalName("Bancos");
o1.setLocalImage(R.drawable.visa);
Local o2 = new Local();
o2.setLocalName("Gasolineras");
o2.setLocalImage(R.drawable.gas);
Local o3 = new Local();
o3.setLocalName("Hospitales");
o3.setLocalImage(R.drawable.hospital);
Local o4 = new Local();
o4.setLocalName("Restaurantes");
o4.setLocalImage(R.drawable.restaurant);
Local o5 = new Local();
o5.setLocalName("Tiendas");
o5.setLocalImage(R.drawable.shop);
m_locals.add(o1);
m_locals.add(o2);
m_locals.add(o3);
m_locals.add(o4);
m_locals.add(o5);
Log.i("Locales añadidos ", ""+ m_locals.size());
} catch (Exception e) {
Log.e("BACKGROUND_PROC", e.getMessage());
}

if(m_locals != null &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; m_locals.size() > 0){
for(int i=0;i<m_locals .size();i++)
m_adapter.add(m_locals.get(i));
}

m_adapter.notifyDataSetChanged();

}

[tweetmeme] No es necesario que el ListView sea lo único que se vea dentro del Layout. Podéis añadir botones, otros layouts o lo que os apetezca. Éste código sólo se encarga de rellenar el ListView y no afectará a otros componentens. Como nota interesante hemos añadido el envio de mensajes al Log del sistema. Tal y como lo hemos echo veremos en Log el número de locales añadido al ListView aunque, como os imaginais, la utilidad del Log es muchísimo más amplia.

screenshot1

Código fuente:

http://mobile.davidocs.com/wp-content/plugins/downloads-manager/img/icons/winrar.gif download: IconListView (44.94KB)
added: 03/08/2009
clicks: 2044
description: ListView que se compone de un icono y un texto.

Comparte:
  • Facebook
  • Bitacoras.com
  • Meneame
  • Wikio IT
  • Digg
  • del.icio.us
  • FriendFeed
  • HackerNews
  • Technorati

Entradas relacionadas:

  1. Cómo instalar el teclado del HTC Hero en el HTC Magic
  2. Tratamiento de ficheros XML con Android
  3. Colección de iconos e imágenes para Android
  4. Creando la primera aplicación con Android
  5. Google Maps con Threads

14 Comentarios to Cómo añadir iconos a un ListView en Android

Avatar

Addison

agosto 20th, 2009 at 7:36 PM

Muy bien, muy bien!!!

Gran tutorial. Mira que he buscado por ahí tutoriales sobre este tema, y no había manera. Todos ellos dejaban un gran interrogante: como instanciar views a partir de un layout especificado en un xml. Imaginaba que era con un LayoutInflater, pero no sabía como obtenerlo!

Voy a probar. Otra vez, gracias por el post.

Avatar

David González

agosto 25th, 2009 at 10:28 AM

Hola Addison,

Me alegro de que te haya servido de ayuda.

Saludos!

Avatar

David

septiembre 13th, 2009 at 9:07 PM

Excelente este tutorial. Estoy recien empezando con android y este tutorial me sirvio de gran ayuda

Avatar

David González

septiembre 15th, 2009 at 8:30 AM

Me alegro de que te haya servido, cualquier duda que tengas no dudes en comentarla. Saludos.

Avatar

Miguel A. Jorquera

enero 26th, 2010 at 6:53 PM

¿Se podría poner en cada fila del ListVeiw un TableLayout generado desde una clase?

Quisiera que apareciera en cada fila una matriz de números y que al hacer operaciones en ella, se añadan a la lista del ListView.

¿cómo se podría hacer esto? Gracias.

Avatar

Droido

marzo 24th, 2010 at 4:52 PM

Gracias por el tutorial.

El archivo fuente no se puede descargar :(

Avatar

Maragues

abril 6th, 2010 at 10:05 AM

Muy buen tutorial, muchas gracias por compartirlo.

Lo único que me dio fallo fue el método getSystemService, al que tuve que ponerle nuestro objeto context delante

mContext.getSystemService

Avatar

Yovany

abril 17th, 2010 at 4:29 AM

Felicidades, Muy buen material!

Lo probare y les comentare como me fue.

Saludos

Avatar

arieluko

junio 23rd, 2010 at 11:58 PM

muy bueno el tutorial, muchas gracias!!!

Avatar

Gustavo Pedreros

diciembre 20th, 2010 at 11:52 PM

Hola estimado, se agradece la información, baje el código y lo hice correr (se ve bonito, pero un tanto lento), estaré revisándolo. Te cuento más tarde como me va. Muchas gracias por ayudar con tu conocimiento =).

PD: murieron las ss, por si te animas a ponerlas de nuevo =P

Avatar

Victor

abril 1st, 2011 at 4:35 PM

Hey men muchas gracias, pero k onda podrías explicarme porque
La aplicación anda muy lenta, porfa ia intente hacerlo pero la Vds. Raramente

Avatar

Carpio

mayo 12th, 2011 at 10:00 PM

Tremendo tutorial!! estaba buscando para meter data en un ListAcitvity y funciono al pelo!

gracias!!

Avatar

Carlos

noviembre 22nd, 2011 at 5:19 PM

Hola creo que podrías ayudarme tengo algo parecido que es un xml que contiene un textview con un checbox, lleno con un cursor el listview , el problema va cuando le hago clik a un chekbox este se marca sin problema pero al hacer scrooll en la lista aparece otro elemento como si le hubiera dado click tambien, segun lei es por el mismo sistema de android que usa la vista impresa para todas las que a continuacion le siguen el problema es que no le doy como solucionarlo aca te pego mi clase para ver si puedes ayudarme a solucionarlo. Gracias

public class ingredientes extends ListActivity {
/** Called when the activity is first created. */

protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.ingredientes);
db = (new DatabaseHelper(this)).getWritableDatabase();
cursor = db.rawQuery(
“SELECT _id, nombre_ingrediente FROM ingredientes”, null);
/*
* adapter = new SimpleCursorAdapter( this,
* R.layout.listado_ingredientes, cursor, new String[]
* {“nombre_ingrediente”}, new int[] {R.id.txt_nombre_ingrediente});
* setListAdapter(adapter);
*
*
* }
*/
setListAdapter(new CheckboxCursorAdapter(this,
R.layout.listado_ingredientes, cursor,
new String[] { “nombre_ingrediente” },
new int[] { R.id.txt_nombre_ingrediente }));

}

public class CheckboxCursorAdapter extends SimpleCursorAdapter {

private Cursor c;
private Context context;

public CheckboxCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;

}

public View getView(int pos, View inView, ViewGroup parent) {
ViewHolder holder = null;
View v = inView;
if (v == null || !(v.getTag() instanceof ViewHolder)) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listado_ingredientes, null);
holder = new ViewHolder();
holder.txtingrediente = (TextView) v
.findViewById(R.id.txt_nombre_ingrediente);
holder.cBox = (CheckBox) v.findViewById(R.id.chkItem);
v.setTag(holder);
} else {

holder = (ViewHolder) v.getTag();
}
this.c.moveToPosition(pos);

holder.txtingrediente.setText(this.c.getString(this.c
.getColumnIndex(“nombre_ingrediente”)));

return (v);

}

}

private class ViewHolder {
CheckBox cBox;
TextView txtingrediente;
}

public void buscar_recetas1(View view) {

// prueba de array para mandar con el intent hasta que pueda capturar
// los checkbox marcados
int numeros[] = { 1, 2, 3 };

Intent intent = new Intent(this, resultado_recetas.class);
intent.putExtra(“idingredientes”, numeros);

startActivity(intent);

}

}

Avatar

Juccis

enero 11th, 2012 at 6:49 PM

Saludos muy buen tutorial, tengo una pregunta cuando cambio el Layout en iconrows.xml de Relative
a Linear ya no me funciona el clic sobre la Lista???

como podria solucionarlo???

Comment Form

De qué va esto?

La comunidad de desarrollo sobre Android e iPhone en castellano es algo limitada, así que hay que sumar, desde aqui intentaré aportar mi granito de arena y ayudar a quien lo necesite. No dudes en preguntar cualquier duda, entre todos los solucionaremos.

Tutoriales

Photostream

tuto3-1tuto2-1tuto1-8tuto1-7