«

»

feb 02 2012

Personalizando nuestro SeekBar

Un elemento muy útil y que usaremos en más de una ocasión es el SeekBar o ProgressBar de Android, pero este, al igual que otros muchos elementos de sistema existirán ocasiones en los que no se ajusten a nuestras necesidades, por eso hoy os contamos como personaliza a vuestro gusto y acorde con vuestras aplicaciones este elemento que Android nos proporciona.


Lo primero que tenemos que conocer antes de enfrentarnos a este tutorial es que es una imagen 9-patch y si aun no lo sabéis os recomiendo pasar por el siguiente post:

¿Que son imágenes 9-patch en Android?

 

PASO 1 – IMAGES DRAWABLES

Antes de comenzar a crear nuestros XML Drawables deberemos tener claras las partes de un SeekBar y tener listas las imágenes que deberemos usar.

 

 

Para el background tendremos una imagen 9-patch para que así se ajuste a los tamaños cambiantes que el SeekBar pueda experimentar en función de nuestras necesidades, el thumb sera una imagen png de nuestro gusto y para el caso del progress que os mostramos el caso es algo más complejo. En nuestro caso el progress está formado por dos elementos (a continuación os explicamos cómo), por un lado la zona azul generada por código y por otro las bandas grises que se trata de una imagen con transparencia repetible en el espacio. Estos son los recursos que necesitaremos para comenzar si no los teneis no os preocupeis, al final del post os enlazamos el proyecto en Google Code y en el incluimos estos recursos. No lo he dicho pero estos recursos los tendremos alojados en res/drawable.

 
 
PASO 2 – SEEKBAR PROGRESS DRAWABLE

Ahora crearemos un XML drawable en /res/drawable que nombraremos seekbar_progress_bg y que será el encargado de ir coloreando la barra conforme el progreso se vea incrementado.

 

<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <clip>
            <shape>
                <gradient
                    android:startColor="#FF5e8ea3"
                    android:centerColor="#FF32a0d2"
                    android:centerY="0.1"
                    android:endColor="#FF13729e"
                    android:angle="270"
                />
            </shape>
        </clip>
    </item>
    <item>
        <clip>
        <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
            android:src="@drawable/stripe_bg"
            android:tileMode="repeat"
            android:antialias="true"
            android:dither="false"
            android:filter="false"
            android:gravity="left"
        />
        </clip>
    </item>
</layer-list>

 

Este drawable estará compuesto por dos partes, un fondo con gradiente y la imagen semitransparente repetible que comentábamos en el paso 1 y que se superpondrá sobre el fondo. Para más información puedes revisar la documentación oficial Android drawable, especialmente la sección de bitmap y shape.

 

PASO 3 – SEEKBAR BACKGROUND DRAWABLE

En este paso crearemos el XML Drawable que lo englobará todo y que será el que pasaremos como parámetro a nuestro SeekBar. Lo llamaremos seekbar_preogress.xml y lo guardaremos en /res/drawable.

 

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <nine-patch
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:src="@drawable/seekbar_background"
            android:dither="true"
         />
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                    android:startColor="#80028ac8"
                    android:centerColor="#80127fb1"
                    android:centerY="0.75"
                    android:endColor="#a004638f"
                    android:angle="270"
                />
            </shape>
        </clip>
    </item>
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/seekbar_progress_bg"
    />
</layer-list>

 

Es importante llegados aquí indicar bien los id para que android entienda a que parte del SeekBar corresponde cada Drawable. El primer elemento correspondería con el 9-patch que comentábamos en el paso 1 y que sería el fondo del SeekBar y el tercer elemento es el que hemos creado en el paso 2 y que corresponde con la zona de progreso. El segundo elemento correspondería con el progreso secundario, un progreso alternativo que podría mostrarse pero que el caso que procede no mostraremos.

 

PASO 4 – PONIENDOLO TODO JUNTO

Llegados este puntos solo nos queda usar nuestros drawables en el SeekBar que queramos, para ello bastara con indicar el atributo progressDrawable el drawable que hemos creado en el paso 3.

 

<SeekBar
        android:id="@+id/frequency_slider"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="0"
        android:secondaryProgress="0"
        android:progressDrawable="@drawable/seekbar_progress"
        android:thumb="@drawable/seek_thumb"
/>

 

Si queréis cambiar el thumb este se indicará directamente en el atributo llamado igual, aquí le indicaremos el nombre del recurso que usaremos como imagen a tal efecto.

 

Y con esto hemos terminado y solo te quedaría compilar y ejecutar tu proyecto para ver que tal queda. A continuación os dejamos el enlace al proyecto con los recursos para vosotros mismos los probéis.

 

Codigo Fuente | Google Code
Via | IngensBlogs

 

Acerca del autor

JMPergar

Mobile Developer at @BeRepublic & Founder of @AndroCode. Silver Speaker & Member of Core Team at @GDGBarcelona.

  • iSuriv

    Me parece genial, Incluso podían algunos developers revisar un SeekBar, que lo deja muy grande.

    Creo que también se puede cambiar el tamaño de alto no?.

  • Guillermo

    Hola, enhorabuena por el artículo. Lo he integrado todo y funciona pero hay un problema extraño. A las tres primeras veces que ejecuto mi acción (reproducción de audio), el thumb de la seekbar se me actualiza correctamente, pero no así el relleno de lo que ha progresado en ese tiempo, sólo carga el primer fragmento de la imagen, lo que en tu ejemplo sería el bitmap stripe_bg. Ahora viene lo más curioso, que es que a la siguiente ejecución sí se va rellenando correctamente en funcion del avance de la seekbar.

    Me estoy volviendo loco con esto, ¿3 ejecuciones y a la siguiente sí que rellena bien? ¿Qué estoy haciendo mal?

    • http://www.linkedin.com/in/jmpergar JMPergar | Editor Jefe

      Con los datos que me proporcionas me quedo corto para darte una conclusión, si pudiera ver más quizás podría ayudarte.

  • Lucio

    una pregunta, tengo dibujada una linea de la siguiente manera;
    class Lienzo extends View {
    public Lienzo(Contex context){
    super(context);
    }
    protected void onDraw(Canvas canvas){
    canvas.drawRGB(255,255,0);
    Paint pincel1 = new Paint ();
    pincel1.setARGB(255,255,0,0);
    pincel1.setStrokeWidth(4);
    canvas.drawLine(x1,y1,x2,y2,pincel1);
    }

    necesito modificar con un seekbar el tamaño de la linea que estoy dibujando, en si lo que quiero es dibujar una onda cuadrada y ajustar su tamaño, soy nuevo en esto, si me pudiera ayudar le estaria muy agradecido, saludos

    • http://www.linkedin.com/in/jmpergar JMPergar | Editor Jefe

      Pues modifica el valor de una variable con el seekbar y dibuja la linea en función de este valor. Y sin acritud, el tema que preguntas no tiene relación con este post en cuestión.