jueves, 19 de septiembre de 2013

View personalizada en Android

Introducción

A continuación se mostrará cómo podemos construir nuestros propios controles, para solucionar necesidades puntuales que no están contempladas en la API de Android.
En este caso, a modo de ejemplo, construiremos un “NumericUpDown” o “NumberPicker”. Este control que apareció con la versión de la API 11 (Android 3.0 Honeycomb), no existe en las versiones anteriores.
La función de este control es simple: un botón para incrementar y otro para decrementar un valor numérico. Nos permite controlar que el usuario solo cargue números y que éstos estén dentro del rango que le indicamos.

Cómo comenzar

Para comenzar con nuestro proyecto, crearemos un proyecto de Android estándar. No hará falta que tenga una Activity, aunque sirve agregarla para hacer pruebas de nuestro proyecto.

Layout


Nuestro Layout será muy simple: un LinearLayout con orientación vertical, que dentro contendrá sólo 3 controles: un botón para incrementar la cuenta, un TextView para mostrar el valor y otro botón para decrementar la cuenta. Llamaremos al archivo layout_updown.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

    <Button
    android:id="@+id/btnIncremento"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="@dimen/button_text_size"
    android:text="@string/boton_incremento" />

    <TextView
    android:id="@+id/txtValor"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="@string/valor_inicial"
    android:textSize="@dimen/text_size"
    android:gravity="center_horizontal"
    android:padding="@dimen/text_padding" />

    <Button
    android:id="@+id/btnDecremento"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="@dimen/button_text_size"
    android:text="@string/boton_decremento" />

</LinearLayout>

Nuestra clase personalizada

Antes que nada, generaremos un Package personalizado, con el cual luego referenciaremos a nuestra View. En nuestro caso utilizaremos ar.com.gnutnfra.frdnumericupdown. Dentro del Package colocaremos un archivo de clase, el cual extenderá de la clase LinearLayout.

public class FrdNumericUpDown extends LinearLayout {
    // CODIGO
}

Al heredar de LinearLayout, nos obligará a sobrecargar los constructores:

public FrdNumericUpDown(Context context) 
{
          super(context);
          crearVista (context);
     }

    public FrdNumericUpDown(Context context, AttributeSet attrs)     {
          super(context, attrs);
          crearVista (context);
    }

Utilizaremos nuestro método crearVista, para crear el objeto View desde nuestro archivo XML de layout. En un principio nos alcanzará con colocar estas líneas dentro del método:

// Creamos el inflater y traemos la vista del XML
LayoutInflater inflater = LayoutInflater.from(context);
vista = inflater.inflate(R.layout.layout_updown, null);

// Agregamos nuestra vista a nuestro objeto Layout
this.addView(vista);

Nuestro proyecto, una biblioteca

Transformar nuestro proyecto Android en una biblioteca es muy sencillo. Primero tenemos que ir a las propiedades del proyecto (Click derecho sobre el nombre del proyecto->Propiedades). Vamos a Android y tildamos Is Library en la parte central inferior:

Agregar la biblioteca a nuestro proyecto

Teniendo abierto ambos proyectos (la biblioteca y el proyecto desde el cual lo utilizaremos), tenemos que ir a las propiedades del proyecto donde queremos usar el control (Click derecho sobre el nombre del proyecto, Propiedades). Vamos a Android y clickeamos Add... en la parte central inferior.
Luego aparecerá un selector con nuestros proyectos librería:


Representar nuestra View en el proyecto

Para mostrar nuestra nueva View personalizada en el proyecto de aplicación, debemos ir a editar el XML del Layout correspondiente e insertar este código:

<ar.com.gnutnfra.frdnumericupdown.FrdNumericUpDown
    android:id="@+id/NumericUpDownPersonalizado"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Notemos que ar.com.gnutnfra.frdnumericupdown es el nombre de nuestro Package, y FrdNumericUpDown es el nombre de nuestra clase.