DesarrolloLibre

Desarrollo Web, Android, juegos y mucho más

Categorias
18-07-2017

En esta entrada veremos cómo crear un sencillo SeekBar mediante la API de Canvas en Android; nuevamente haremos uso del proyecto de Telegram que puedes encontrar en la sección de recursos en esta misma web, y ya con este vendría siendo la segunda entrada que le dedicamos a analizar un poco ciertas secciones de la aplicación de Telegram:

Cómo realizar una actividad de presentación animada en Android con ViewPager

El SeekBar a realizar es realmente sencillo, solo consiste de una barra lateral (un rectángulo achatado) y una circunferencia que hará la vez de control y es la que manipularemos mediante un clic o "gesto" para desplazarla de derecha a izquierda y viceversa.

Definiendo las bases: la estructura de la actividad

Primero debemos definir la estructura de nuestra actividad que es la que dará soporte al SeekBar dibujado mediante Canvas en una otra clase; en el layout de nuestra actividad hacemos realmente poco; simplemente definimos un layout vacío como el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/cons"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context="com.presentacion.desarrollolibre.audioplayer.MainActivity">
</LinearLayout>

Ya nos encargamos desde la actividad de crear un FrameLayout con unas dimensiones fijas de 300 x 300 empleando el siguiente código Java:

SeekBarView seekBarView = new SeekBarView(MainActivity.this);
FrameLayout.LayoutParams myFrameLayoutParams = new FrameLayout.LayoutParams(300,300);
seekBarView.setLayoutParams(myFrameLayoutParams);
setContentView(seekBarView);

La clase SeekBarView para dibujar el SeekBar mediante Canvas

Como veremos en el experimento, la clase SeekBarView extiende de la clase FrameLayout y por lo tanto debe sobrescribir ciertos métodos de esta clase; en el método constructor de la clase nos encargamos de crear un objeto de tipo Paint que nos permite dibujar formas geométricas (nuestro rectangulo y circulo) y dibujarlo dentro de un Canvas; ademas definimos dos variables con un tamaño fijo que nos serviran para otro propósito:

thumbWidth = dp(24);
thumbHeight = dp(24);

Estas variables se encargan de definir la posición del rectángulo que dibujamos con el método onDraw() de esta clase SeekBarView; el método onDraw() que sobreescribimos, se encarga de crear el lienzo/canvas y dibujar las figuras geométricas (rectángulo y círculo) en nuestro lienzo/canvas:

canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - dp(1), thumbWidth / 2 + thumbX, getMeasuredHeight() / 2 + dp(1), outerPaint1);
El método getMeasuredHeight() retorna el largo del contenedor que definimos en la actividad, que para este experimento es de 300.
El método getMeasuredWidth() retorna el ancho del contenedor que definimos en la actividad, que para este experimento es de 300.

Además de una barra que dibujamos con la función anterior de drawRect, dibujamos un círculo con ayuda de la primitiva drawCircle.

canvas.drawCircle(thumbX + thumbWidth / 2, y + thumbHeight / 2, dp(pressed ? 8 : 6), outerPaint1);

Por último se crea un método onTouch que se ejecuta para mover el círculo según el toque del usuario sobre el Canvas (una especie de evento onClick mantenido). El método onTouch es bastante interesante ya que se realizan los cálculos para reubicar la bola según la actualización de la variable thumbX la cual se actualiza según la posición del clic del usuario en la SeekBar; el método onTouch se encarga de llamar de manera automática el método onDraw y de esta forma se redibuja la bola según la posición actualizada:

boolean onTouch(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        getParent().requestDisallowInterceptTouchEvent(true);

        int additionWidth = (getMeasuredHeight() - thumbWidth) / 2;
        if (thumbX - additionWidth = 0 && ev.getY() SeekBarDrag((float) thumbX / (float) (getMeasuredWidth() - thumbWidth));
            }
            pressed = false;
            invalidate();
            return true;
        }
    } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
        if (pressed) {
            thumbX = (int) (ev.getX() - thumbDX);
            if (thumbX  getMeasuredWidth() - thumbWidth) {
                thumbX = getMeasuredWidth() - thumbWidth;
            }
            invalidate();
            return true;
        }
    }
    return false;
}

En el método anterior onTouch existen varios eventos para; tenemos la constante ACTION_DOWN que se ejecuta al momento de iniciar el "gesto" o el clic de la persona en el Canvas y la constante ACTION_UP que se ejecuta al momento de terminar el "gesto" o el clic de la persona en el Canvas.

A raíz de estos estados, se actualiza la variable thumbX que es la que "mueve" o permite redibujar la bola mediante el método onDraw().

De igual manera puedes encontrar el código fuente en github al inicio y final de esta entrada:


Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Generador de launcher para Android sin padding

Generador de launcher para Android sin padding

Wave World con Canvas

Wave World con Canvas

Paleta de colores para el Material Design

Paleta de colores para el Material Design

Algunos artículos que te pueden interesar

Detectando los eventos de teclado con Canvas

Detectando los eventos de teclado con Canvas

En esta entrada veremos un pequeño experimento en donde con el Canvas mediante los eventos de teclados específicamente emplearemos las flechas de direcciones del teclado.

Andrés Cruz 07-12-2015

Cómo incrustar un video de Youtube en Android

Cómo incrustar un video de Youtube en Android

Se explica cómo incrustar un video de Youtube en una aplicación Android empleando la API nativa de Youtube creada por Google.

Andrés Cruz 20-10-2016

Creando un Punto de Interés con Realidad Aumentada en Wikitude Parte 2

Creando un Punto de Interés con Realidad Aumentada en Wikitude Parte 2

Trataremos sobre cómo vincular nuestro Architect World (código JavaScript) con el código nativo (código Java) de la aplicación para obtener y actualizar constantemente los Puntos de Interés según la posición del dispositivo.

Andrés Cruz 15-01-2015