Cómo crear un watchface Android Wear  parte 4

Antes de continuar con este tutorial de cómo crear un watchface Android Wear…

Hola, por aquí ando de nuevo con la última parte del tutorial donde te explico como crear un watchface Android Wear para que puedas hacerte uno tu mismo si te animas, en la primera parte del tutorial vimos como configurar el entorno de trabajo y crear nuestro proyecto, en la segunda parte del tutorial vimos las configuraciones de los archivos xml, gradle y como empezar a pintar en el canvas, en la tercera entrega entramos a fondo explicando cosas como qué es un pincel, los métodos necesarios para pintar con el onDraw, etc. En esta parte vamos a ver otras curiosidades como aplicar un efecto o una máscara a un paint y como extra veremos cómo recuperar la batería del reloj y mostrarla por pantalla.

Puedes encontrar el código fuente del watchface completo en: GitHub

 

1 Variables necesarias para los segundos

Lo primero que necesitaremos será añadir las variables que vamos a usar para añadir un efecto de tipo DashPath a los segundos que es como una rejilla en la que podemos establecer intervalos donde el paint se muestra o no, no os preocupéis, lo veremos más adelante en funcionamiento y quedará más claro, de momento añadir estas variables dentro de la clase Engine:

//pincel de los segundos
Paint pincelAzulBlur = new Paint();

//este parametro se usa para determinar las direcciones del efecto
float pathEffectLen;
//este es el efecto en si
DashPathEffect dashPathEffect;
final float PI = (float) Math.PI;//media circunferencia

He declarado un pincel para pintar los segundos, una variable de apoyo que calcularemos más adelante y un DashPathEffect que es nuestro efecto a aplicar al paint, podéis ver más efectos en la página oficial, por último tenemos en número PI.

2 Método onCreate

En este método vamos a inicializar el paint de lo segundos con una máscara de tipo BLUR para que veáis como se inicializa esta máscara:

//se utilizara para pintar los segundos
pincelAzulBlur.setStyle(Paint.Style.STROKE);
pincelAzulBlur.setColor(Color.CYAN);
pincelAzulBlur.setMaskFilter(new BlurMaskFilter(10f, BlurMaskFilter.Blur.OUTER));
pincelAzulBlur.setStrokeJoin(Paint.Join.ROUND);
pincelAzulBlur.setStrokeWidth(15f);

Como os comentaba dentro de este método del Engine he inicializado el pincel para que sea una linea de color cian con una máscara de tipo BLUR OUTER (aquí podéis más filtros), con unos bordes redondeados (con el Paint.Join que lo tenéis aquí) y un tamaño de 15.

3 Método onSurfaceChanged

Aquí vamos a inicializar el efecto que vamos a aplicar al pincel de los segundos, así que añadimos el siguiente código en este método:

//calculamos la longitud que tomaremos para cada segundo
pathEffectLen = (PI * width) / 60f;
//creamos los efectos para el casillero de los segundos
dashPathEffect = new DashPathEffect(
            new float[]{pathEffectLen - 6f, 4f},
            0f);
pincelAzulBlur.setPathEffect(dashPathEffect);

Calculamos la longitud de cada segundo y creamos el efecto pasando dos parametros,uno es cuando queremos que el efecto este en ON y el efecto este en OFF (el efecto es como una rejilla la cual dará la sensación de segundero) con lo que le pasamos un array de al menos dos elementos y luego el ángulo que tomará el efecto, como ya lo tenemos inicializado lo añadimos a nuestro paint sin contemplaciones 🙂

4 Método onDraw

Ya tenemos todo lo necesario para pintar los segundos, recordad que en el modo ambiente el canvas no se repinta cada segundo sino que se repinta cada minuto, por lo que los segundos no deberían mostrarse en el modo ambiente, simplemente no los pintes. Ahora vamos a ver el código que hay que añadir para mostrar los segundos por la pantalla:

//segundos
float seconds = mCalendar.get(Calendar.SECOND) +
mCalendar.get(Calendar.MILLISECOND) / 1000f;

//angulo de la porcion de cada segudno
float asec = seconds / 60f * TWO_PI;

final RectF ovalSec = new RectF();
//calculamos el angulo de fin del arco
float finSec = (180f * asec) / PI;
//longitud del cuadrado que represntara cada segundo
float longSegundos=20f;
//le damos medidas a la base del arco
ovalSec.set(
   bounds.left + longSegundos,
   bounds.top + longSegundos,
   bounds.right - longSegundos,
   bounds.bottom - longSegundos
);
//pintamos el arco desde -90 que es desde las 12 en punto, no pintamos centro
canvas.drawArc(ovalSec, -90f, finSec, false, pincelAzulBlur);

Primero obtenemos los segundos del calendario y el ángulo para pintar el arco que vamos a pintar con nuestro paint, después creamos un RectF para setear sus medidas, como sabemos el principio de donde pintaremos el arco (las 12:00) solo tenemos que calcular hasta donde tenemos que llegar y con esos datos simplemente pintamos el arco, el resultado tiene que quedaros así al ejecutar:

Pantallazo del resultado

Pantallazo del resultado

En el pantallazo vemos como hemos creado una linea semidiscontinua gracias al efecto, le hemos dado un efecto de luz de fondo con la máscara.

 

5 Obtener la batería del reloj:

Como extra, os dejo esto que para quien no lo sepa le vendrá muy bien porque es sencillito y no se tarda nada en hacerse, primero nos vamos a declarar un broadcast para obtener la batería tal que así:

int level=0;
/**
* broadcast para leer el nivel de bateria del reloj
*/
final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
      level= intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
   }
};

Este nos dará el valor de la batería para que podamos mostrarlo, así que ahora vamos a registrarlo y desregistrarlo en el método onVisibilityChanged (cuando se ve lo registramos y cuando no se ve lo desregistramos), para registrarlo:

IntentFilter filterCambioDeBateria = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
ServicioMain.this.registerReceiver(mBatteryReceiver, filterCambioDeBateria);

Y para desregistrarlo:

ServicioMain.this.unregisterReceiver(mBatteryReceiver);

En el método onDraw vamos a pintarlo tal que así:

if (level!=-1){
    //si hemos obtenido lectura de la bateria la mostraremos
    canvas.drawText(String.valueOf(level)+"%",xTextoBat,yTextoBat, pincelInfoBat);
}
else{
    //si no pintaremos solo el texto
     canvas.drawText("0%",xTextoBat,yTextoBat, pincelInfoBat);
}

Bueeeeeeeeeno, no me digáis que no sabéis los valores de xTextBat y su respectiva Y, estos pueden ser los que queráis en mi caso yo lo voy a pintar en el centro de la Y y en el primer cuarto de la X más o menos, vamos a ver como queda:

Pantallazo tutorial watchface batería

Pantallazo tutorial watchface batería

Ahí está nuestro porcentaje de batería y nuestro super reloj que es muy sencillo pero muy didáctico.

Sin más agradeceros el llegar hasta aquí en la lectura, espero que os sea de utilidad y si veis cualquier cosa que tenga que cambiar por que me he equivocado (todos somos humanos…) dejadme un comentario y lo arreglo ;).

 

Hasta el próximo tutorial!!!!!!