Construcción de un control personalizado en Android

0
12443

Construcción de un control personalizado en Android

Introducción

En muchas ocasiones es muy interesante crear nuestros propios controles personalizados para poder reutilizarlos rápida y cómodamente en el futuro.
En este tutorial vamos a ver un ejemplo de como crear y usar un control personlizado sencillo.

Manos a la obra! construcción del control personalizado

A continuación construiremos un control que nos permita cómodamente elegir mediante una barra de progreso un número entre un determinado intervalo válido, además nos permita personalizar:

  • El título
  • El valor máximo.
  • El valor por defecto seleccionado.

Si deseas el código fuente, puedes descargártelo aquí .
(Está autocomentado, no creo que tengas problemas si tienes una base de programación en Android.)

Captura de pantalla de la aplicación a construir:

El control personalizado que construiremos está resaltado con un borde azul.

Captura de pantalla de la aplicación

Interface gráfico de la aplicación (la captura de pantalla)

Observe como definimos declarativamente la pantalla con el control personalizado es.carlosgarcia.widget.SeekBarCustom que construiremos posteriormente:




	
	
	

es.carlosgarcia.MainActivity

Único Activity de la aplicación.

package es.carlosgarcia;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import es.carlosgarcia.widget.SeekBarCustom;

/**
 * Control personalizado que representa una barra de progreso con un título con:
 * @param min: 		Valor mánimo
 * @param progress: Valor actual
 * @param text:		Título mostrado
 * @author Carlos García. http://www.carlos-garcia.es
 */
public class MainActivity extends Activity implements OnClickListener {
	private Button 		  btn;
	private SeekBarCustom seek;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        this.setContentView(R.layout.main);
        this.btn  = (Button) this.findViewById(R.id.button1);
        this.seek = (SeekBarCustom) this.findViewById(R.id.barId);
        this.btn.setOnClickListener(this);
    }

    /**
     * Cuando hacemos clic en el botón invocamos un método personalizado y especifico del control
     */
	@Override
	public void onClick(View v) {
		if (seek.isValueSelected()){
			Toast.makeText(this, "Estupendo!!", Toast.LENGTH_LONG).show();
		} else {
			Toast.makeText(this, "Seleccione un valor, por favor.", Toast.LENGTH_LONG).show();
		}
	}
}

es.carlosgarcia.widget.SeekBarCustom

Clase que define el control personalizado que deseamos construir (lo resaltado en azul en la captura de pantalla anterior).

Observe como:

  • Construimos el control combinando (o componiendo) varios controles ya definidos (LinearLayout, SeekBar y TextView)
  • Leemos los atributos que hemos definido en el XML del GUI. (max, progress, text).
package es.carlosgarcia.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

/**
 * Control personalizado que representa una barra de progreso con un título con:
 * @param min: 		Valor mínimo
 * @param progress: Valor actual
 * @param text:		Título mostrado
 * @author Carlos García. http://www.carlos-garcia.es
 */
public class SeekBarCustom extends LinearLayout implements OnSeekBarChangeListener {
	private static final String NS 		 = "http://schemas.android.com/apk/res/android";
	private static final String PROGRESS = "progress";
	private static final String MAX		 = "max";
	private static final String TEXT	 = "text";
	
	private int		 resCode;
	private SeekBar  bar;
	private TextView caption;
	
	public SeekBarCustom(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.initUI(attrs);
	}
	
	/**
	 * Inicializamos el control leyendo los atributos personalizados max, progress y text
	 * @param attrs
	 */
	private void initUI(AttributeSet attrs){
		this.caption = new TextView(this.getContext());
		this.bar   	 = new SeekBar(this.getContext());
		this.resCode = attrs.getAttributeResourceValue(NS, TEXT, 0);
		
		this.setOrientation(LinearLayout.VERTICAL);
		this.addView(caption);
		this.addView(bar);

		int progress = attrs.getAttributeUnsignedIntValue(NS, PROGRESS, 1);
		caption.setText(getResources().getString(resCode, progress));
		
		bar.setMax(attrs.getAttributeUnsignedIntValue(NS, MAX, 100) + 1);
		bar.setProgress(progress);
		
		
		bar.setOnSeekBarChangeListener(this);
	}

	/**
	 * Permite al usuario establecer el valor, validamos que sea un valor correcto.
	 */
	public void setProgress(int p){
		if ((p < 0) || (p > bar.getMax())){
			throw new IllegalArgumentException();
		}
		bar.setProgress(p);
	}

	public int getProgress(){
		return bar.getProgress();
	}	
	
	/**
	 * Indica si el usuario ha seleccionado algún valor
	 */
	public boolean isValueSelected(){
		return (bar.getProgress() > 0);
	}
	
	/**
	 * Cambiamos el título del control cuando el usuario mueve el SeekBar.
	 */
	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
		caption.setText(getResources().getString(resCode, progress));
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {}
}

Archivo de recursos de mensajes /res/string.xml

Nota: Si desea traducirlo automáticamente a otros idiomas, puede hacerlo a mano o usar la aplicación toi18n.



    Demo: Control Personalizado
    http://www.carlos-garcia.es
    Eliga un número del 1 al 10.  (Actual %1$d)
    Aceptar

Conclusiones

Como veis no es difícil crear estos controles y reutilizarlos en un futuro o incluso crearos vuestras propias librerías de componentes..

Espero que os haya sido útil, un saludo.
Carlos García, http://www.carlos-garcia.es.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad