DecoView, una librería Android para hacer maravillas con gráficos circulares en tus apps

Hola a tod@s!!!, ya estoy aquí dando guerra one more time, viendo ayer la final de la Copa del Rey FC Barcelona VS Sevilla (no me gusta el fútbol pero no pierdo las finales por que son más emocionantes) pensé que podía explicar herramientas que me he planteado usar en mi app para cuantificar el día a día. Hoy voy a empezar con esta librería que me he encontrado en The Android Arsenal, DecoView, una librería Android para crear gráficos los cuales podemos animar, podéis ver el video de la app ej. que tienen en la PlayStore y ver como además de original es bonita, los gráficos se parecen mucho a los de GoogleFit, la archiconocida app de fitness de Google.

El proyecto está distribuido con licencia Apache 2 y su web original esta en GitHub.

Bueno sin más rollos vamos al lío y vamos a programar un poco.

1. Requisitos

  1. Yo voy a trabajar con un windows 10.
  2. Android Studio con su SDK, que lo podéis encontrar aquí.
  3. Conexión a internet.
  4. Descargar la librería mediante Gradle en Android Studio

 

2. Crear un nuevo proyecto

Vamos a partir de la base de que ya sabemos algo de programación en Android para no liarnos con cosas fáciles y poder extenderme más en las cosas que tienen más importancia, os pongo los pasos rápidamente:

  1. Abrir Android Studio (evidente jeje)
  2. Crear nuevo proyecto
  3. Nombre de la app y nombre de la compañia (para formar el nombre del paquete)
  4. Seleccionar la versión mínima de Android compatible, yo voy a dejar el nivel de API 15
  5. Seleccionamos un vista para nuestra Activity principal, yo he puesto una Activity en blanco
  6. La nombramos junto a su layout

 

3. Configuración de Gradle, añadiendo la libreria.

Lo bueno de Android Studio es que te facilita la labor gracias a su integración con Gradle, así que solo tenemos que añadir las siguientes lineas a nuestro archivo Gradle de la app:

repositories {
// ...
maven { url "https://jitpack.io" }
}

Y en el Gradle de nuestro modulo app:

dependencies {
compile 'com.github.bmarrdev:android-DecoView-charting:v1.1'
}

Después sincronizamos para que se descargue la dependencia y construya nuestro proyecto. Con esto último ya tenemos listo el proyecto para  empezar a trabajar.

4. Añadir al layout el DecoView Widget

Abrimos nuestro layout principal auto-generado cuando creamos el proyecto y tendremos que añadir el componente que nos ofrece la librería donde se pintarán las gráficas:

<com.hookedonplay.decoviewlib.DecoView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/dynamicArcView"/>

Tengo que aclarar en este punto que DecoView hereda de View así que es como un TextView, ImageView y todos los que descienden de View. Ahora vamos a añadir un TextView (tengo que decir que como elemento padre tengo un RelativeLayout) con el siguiente código:

<TextView
        android:id="@+id/tv_porciento"
        android:layout_centerInParent="true"
        android:textSize="60sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Este TextView lo usaremos para mostrar el tanto por ciento del intervalo que animaremos más adelante. Con esto ya tenemos lo necesario en cuanto a la parte de la vista.

5. El código java para añadir los datos y como se muestran

Ahora vamos a añadir todo el código java necesario para hacer funcionar nuestra gráfica circular animada y que muestre el valor del progreso en el TextView.

En el onCreate() de nuestro Activity vamos a obtener nuestros Widgets para poder trabajar con ellos, así que añadir el siguiente código:

final DecoView arcView = (DecoView)findViewById(R.id.dynamicArcView);
final TextView tvPorciento = (TextView) findViewById(R.id.tv_porciento);

int series1Index = 0;

También me he declarado una variable de tipo entero para guardar el indice de la serie, esto lo utilizaremos más adelante.

Ahora vamos a configurar como se van a ver nuestros datos en el gráfico, para ello vamos a ver el siguiente código con más detalle:

final  SeriesItem seriesItem1 = new SeriesItem.Builder(Color.argb(200, 255, 0, 0))
         .setRange(0, 100, 0)
         .setInitialVisibility(false)
         .setLineWidth(100f)
         .addEdgeDetail(new EdgeDetail(EdgeDetail.EdgeType.EDGE_OUTER, Color.parseColor("#22000000"), 0.4f))
         .setSeriesLabel(new SeriesLabel.Builder("Valor %.0f%%").build())
         .setInterpolator(new DecelerateInterpolator())
         .setShowPointWhenEmpty(true)
         .setCapRounded(true)
         .setInset(new PointF(20f, 20f))
         .setDrawAsPoint(false)
         .setSpinClockwise(true)
         .setSpinDuration(6000)
         .setChartStyle(SeriesItem.ChartStyle.STYLE_DONUT)
         .build();

 series1Index = arcView.addSeries(seriesItem1);

No os preocupéis vamos a ir parámetro a parámetro:

  • Empezamos con el color que vamos a usar en la barra del gráfico, en este caso hemos puesto rojo y con un poco de transparencia.
  • setRange(0,100,0), con esto lo que le indicamos es que el mínimo es 0, el máximo es 100 y partimos de 0.
  • setInitialVisibility(false), indicamos que la visibilidad inicial sea invisible.
  • seLineWidth(100f), le decimos como de gruesa será la barra.
  • addEdgeDetail(new EdgeDetail(EdgeDetail.EdgeType.EDGE_OUTER, Color.parseColor(“#22000000”), 0.4f)), aquí estamos añadiendo un borde exterior de color negro pero muy trasparente para que de sensación de sombreado, el último parámetro indica el ratio con respecto al total.
  • setSeriesLabel(new SeriesLabel.Builder(“Valor %.0f%%”).build()), ponemos la etiqueta que aparece encima donde pondrá también el valor del progreso (en este tutorial tenemos el TextView y la etiqueta para mostrar el progreso así veis como queda en los dos sitios)
  • setInterpolator(new AccelerateInterpolator()), podemos decir que tipo de animación queremos cuando cambie de valor el progreso y puede ser Accelerate/Decelerate, Overshoot, etc, son los mismos de Android y los puedes ver aquí.
  • setShowPointWhenEmpty(true), si queremos mostrar un punto cuando el valor es vacío, si no lo queremos lo marcamos a false.
  • setCapRounded(true) pintamos nuestra barra redondeada, si la queremos cuadrada debemos pasarle false.
  • setInset(new PointF(20f, 20f)), por defecto la librería pinta la barra en el centro con el radio máximo y con esta instrucción lo que hacemos es que nos la pinte más al centro pudiendo así meter varias barras para varias series sin solaparlas (o sí, si es lo que queremos). Para que quede más claro, si queremos meter circunferencias dentro de otras podemos hacerlo con esto.
  • setDrawAsPoint(false) y setSpinClockwise(false), con la primera instrucción indicamos que no queremos que se dibuje como un punto, con  la segunda instrucción le decimos que gire en el sentido de las agujas del reloj.
  • setSpinDuration(6000) esta instrucción indica la duración total de la animación, lo he puesto para explicarlo porque se ve sobreescrito más adelante cuando programemos los eventos pero si no los hubiera seria el comando a usar.
  • setChartStyle(SeriesItem.ChartStyle.STYLE_DONUT) aquí le estamos seleccionando el estilo de nuestra gráfica, a mi personalmente me gustó este.
  • build() y por último lo construimos.

 

Ahora que tenemos como queremos mostrar los datos se lo vamos a decir a nuestro Widget con el siguiente código:

series1Index = arcView.addSeries(seriesItem1);

Recordaréis que le dijimos que no se mostrara al principio, y como la máquina no es tan lista, ahora tenemos que añadir un evento para que se muestre la gráfica inicialmente, además lo haremos con una animación:

arcView.addEvent(
        new DecoEvent.Builder(DecoEvent.EventType.EVENT_SHOW, true)
        .setDelay(1000)
        .setDuration(2000)
        .build()
);

Con esto ya hemos añadido el evento “Mostrar” de nuestra gráfica con un retraso de 1 segundo y una duración total de 2.

Ahora vamos a añadir más eventos para ver como se anima el gráfico y ver las posibilidades que tiene:

arcView.addEvent(new DecoEvent.Builder(25).setIndex(series1Index).setDelay(4000).build());
arcView.addEvent(new DecoEvent.Builder(100).setIndex(series1Index).setDelay(8000).build());
arcView.addEvent(new DecoEvent.Builder(10).setIndex(series1Index).setDelay(12000).build());

Con esto vamos a conseguir que avance al 25% luego al 100% y por último al 10% donde se quedará, como es una animación y no queremos que se solapen hemos dejado un margen de 4 secs para el primero, 8 para el segundo y 12 para el tercero.

Como último vamos a añadirle al TextView el % del progreso de nuestra barra para que se vea en que valor esta actualmente, para ello tenemos que agregar el listener a nuestra gráfica:

seriesItem1.addArcSeriesItemListener(new SeriesItem.SeriesItemListener() {
    @SuppressLint("DefaultLocale")
    @Override
    public void onSeriesItemAnimationProgress(float percentComplete, float currentPosition) {
        //obtenemos el porcentaje a mostrar
        float percentFilled = ((currentPosition - seriesItem1.getMinValue()) / (seriesItem1.getMaxValue() - seriesItem1.getMinValue()));
        //se lo pasamos al TextView
        tvPorciento.setText(String.format("%.0f%%", percentFilled * 100f));
    }

    @Override
    public void onSeriesItemDisplayProgress(float percentComplete) {

    }
});

Dentro del listener calculamos el valor y lo seteamos para que se muestre.

Ya tenemos todo listo, ahora es momento de probar a ver que hemos roto por ahí, que no que es broma, no se rompe nada pero si que queda muuuuyyyy chulo la verdad. Le damos al play en Android Studio y este es el resultado:

 

Captura Ejemplo 1 DecoView Android

Captura 1 Ejemplo DecoView Android

 

Captura 2 Ejemplo DecoView Android

Captura 2 Ejemplo DecoView Android

 

Captura 3 Ejemplo DecoView Android

Captura 3 Ejemplo DecoView Android

Y también os dejo un video en YouTube para que lo veáis  funcionar en directo:

 

Bueno espero que os haya gustado el tutorial sobre esta librería tan chula con la que poder hacer gráficos para nuestras apps fácilmente, ya lo habéis visto, aún así aquí solo nos hemos iniciado ahora os invito a trastearla vosotros.

Sin más me despido de vosotr@s, hasta la próxima y si sentiros libres de comentar las dudas, correcciones o cualquier inquietud que tengáis.