Como crear controles personalizables en Android

Buenas, la semana pasada os deje aprendiendo a aplicar estilos a los controles de Android, y esta semana vamos a crear un control personalizado que utilizaremos repetidas veces en nuestra aplicación. Lo cual nos ayudará a no repetir tanto código en Android.


Lo que vamos a crear es un item para una lista. Este es un ejercicio ni muy simple ni muy complejo que nos permitirá ver varios conceptos de la programación en Android.
Nuestro control dispondrá de los siguientes elementos:

  • Un LinearLayout para contener el resto de elementos.
  • Un ImageView en el cual pondremos una imagen para nuestros items.
  • Un TextView para introducir el texto que querramos en el item.
  • Un Button o ImageButton para ejecutar alguna acción.

El ejemplo lo podéis hacer tanto en el proyecto de nuestra primera aplicación HolaMundo o en un nuevo proyecto. Pero lo mejor es que para cada uno de estos ejemplos que vayamos haciendo os hagáis un proyecto por separado.


Lo primero que vamos a hacer es el archivo donde definiremos el diseño del item, para ello en la carpeta layout, hacemos botón derecho y new->file, le llamamos item_list.xml, este tendrá el siguiente código:

<?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="wrap_content">
<ImageView android:id="@+id/img" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<TextView android:id="@+id/lbl"  android:layout_width="wrap_content" android:layout_height="wrap_content"  />
<Button android:id="@+id/btn" android:text="enviar" android:layout_height="wrap_content" android:layout_width="wrap_content" />

Como podeis ver, para este ejemplo no me voy a parar mucho a dar estilo a los controles.
Lo siguiente es crear una clase que nos permita manipular esta plantilla y darle el comportamiento que queramos.

Para ello en la carpeta res, dentro de nuestro espacio de nombres, (en el primer ejemplo era com.examples.HolaMundo) hacemos botón derecho y new -> class. Le damos un nombre, ItemList, y tiene que heredar de LinearLayout, para ello clicamos en el botón Browse de la sección “supleclass” y empezamos a escribir LinearLayout, aceptamos todo y listo, ya está creada la clase que manejará nuestro item, ahora vamos a hacer que funcione.


Lo primero, abrimos el archivo nuevo que hemos creado, ItemList.java. Eclipse nos avisará que no hemos definido uno de los contructores necesarios por heredar de LinearLayout, nos ponemos con el ratón sobre el nombre de la clase y una ayuda contextual nos dirá que añadamos un contructor, seleccionamos el de un sólo parámetro de tipo “context”.


Os pego el código y dentro os voy explicando con comentarios.

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
on; import android.widget.Ima
import android.widget.But tgeView; import android.widget.LinearLayout;
ItemList extends LinearLayout
import android.widget.TextView; public class { //definimos una variable para la etiqueta, la imagen y el botón
private TextView lbl;
private ImageView img; private Button btn;
//Defínimos un método que nos permita setear desde fuera el texto de la etiqueta
public void setLabelText(String t){ lbl.setText(t); } //Defínimos un método que nos permita setear desde fuera de la clase la imagen.
//Como parámetro pasamos un entero ya queA ndroid hará referencia a los recursos con un entero para cada uno. public void setImage(int resource){ img.setImageResource(resource);
} public ItemList(Context context) { super(context); //Leemos la plantilla que hicimos antes para pintarla en pantalla. R.layout.item_list es una referencia al archivo item_list.xml que creamos antes, para hacer referencia muchos de los archivos de recursos que utilicemos lo haremos de esta forma, no tienen que ser siempre desde layout, pueden estar en drawable, string... String infService = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater li = (LayoutInflater)getContext().getSystemService(infService); li.inflate(R.layout.item_list, this, true); //inicializamos los 3 controles que tenemos haciendo referencia a ellos y convirtiendolos al tipo que corresponda. Podemos tener en otros layouts elementos que se llamen igual pero Android sabe que estamos manejando este layout y que es aquí donde tiene que buscar primero elementos que tengas estos nombres. lbl = (TextView) findViewById(R.id.lbl); img = (ImageView) findViewById(R.id.img); btn = (Button) findViewById(R.id.btn); //definimos una acción para el botón cuando lo pulsemos btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { //En este caso solo cambiamos el texto de la etiqueta lbl.setText("Cambiando texto etiqueta"); } }); } }

Una vez tenemos este archivo acabado vamos al archivo mail.xml y definimos un control en el cual vamos a insetar nuestros items. Para ello podemos añadir un LinearLayout dentro del LinearLayot principal, quedá algo así (solo pongo el LinearLayout que añadimos, el resto de la estructura del archivo main.xml se supone que queda igual) :

<LinearLayout android:id="@+id/lyt" android:layout_width="fill_parent" android:layout_height="wrap_content"></LinearLayout>

Por último, en el archivo de vuestra Activity prinpipal, está en la carpeta src y en el ejemplo de holamundo se llamaba HolaMundoActivity.java, vamos a añadir el siguiente código (Yo lo hice sobre el ejemplo del HolaMundo):

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class HolaMundoActivity extends Activity {
 
//Definimos una variable privada para el contenedor de nuestros items
private LinearLayout lyt;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //Inicializamos el contenedor
        lyt = (LinearLayout) findViewById(R.id.lyt);
        
        //Si ya tuvieramos el contenedor cargado con otros items podríamos limpiar todo lo anterior con lo siguiente
        //En este caso como empezamos sin ningún item no eliminamos nada
        lyt.removeAllViews();
        
        //Definimos un objeto tipo itemlist
        ItemList item;
        
        //Ahora añadiré un par de items de forma manual, pero bien se podrían ir creando leyendo de una base de datos o cualquier otra fuente de datos
        //Llamamos al constructor del objeto
        item = new ItemList(this);
        //Seteamos el texto y la imagen
        item.setLabelText("Texto 1");
        item.setImage(R.drawable.icon);
        //Añadimos el nuevo item al contenedor
        lyt.addView(item);
        
        //Vuelta a empezar para añadir otro item
        item = new ItemList(this);
        item.setLabelText("Texto 2");
        item.setImage(R.drawable.icon);
        lyt.addView(item);
        
        //y así hasta que no tengamos más items       
        
    }

}


En el ejemplo he utilizado una imagen que se añade por defecto a los proyectos de Android, icon.png, vosotros podéis poner unas cuantas imágenes en la carpeta drawable e ir cambiado la línea donde se setea la imagen: item.setImage cada vez por una imagen diferente.

Bueno, esto ya está listo. Ya hemos creado un control personalizado a nuestra medida. No hace nada extraordinario pero es muy útil saber que se pueden hacer este tipo de cosas sobre todo para ahorrar y centralizar el código. No tiene porque ser exclusivamente un elemento de una lista, puede ser un control de login, un botón “me gusta” o lo que se os ocurra que puede aparecer a lo largo y ancho de vuestra aplicación.

Comments are closed.