miércoles, 26 de agosto de 2020

Optimizar MultiStage build en Docker y Maven

 En esta entrada les quiero presentar un truco pequeño sobre como optimizar sus builds en Docker y Maven con tan solo cambiar una linea de código. 

Ya es bien sabido que Docker se ha convertido en una herramienta básica para los desarrolladores al momento de distribuir sus aplicaciones. Los contenedores de docker pueden ser descargados y ejecutados en cualquier ambiente compatible y ademas es uno de los manéjadores de contenedores soportados por kubernetes que se ha vuelto el estándar para correr aplicaciones en la nube. 

No solo eso. Con el soporte de multi-stage builds en Docker es posible támbien simplificar la manera en que las aplicaciones son compiladas y empaquetadas antes de ser distribuidas en su contenedor final. En un build multi-stage docker prepara un contenedor donde se ejecutan algunas instrucciones de compilado / pruebas y el resultado final es copiado a un nuevo contenedor.

Con esto se simplifica la manera en la que nuevos desarrolladores o servidores CI compilan las aplicaciones. Solo es necesario tener docker y poder descargar un contenedor con todas las herramientas ya listas para la compilación. Es este articulo lo haremos con maven. 

Un ejemplo de un multi-stage build con maven y docker, y que ademas se encuentra mucho en proyectos de github, se puede estructurar como sigue.

FROM maven:3.6-jdk-11 as build
WORKDIR /src
ADD * /src
RUN mvn package -DskipTests

FROM adoptopenjdk:11-jre-hotspot
COPY --from=build /src/target/app.jar /app/app.jar
CMD ["java", "-jar", "/app/app.jar"]
EXPOSE 8080

Este método es muy común. Simplemente descargamos un contenedor docker que cuente con maven y java. Luego agregamos todo el proyecto completo al directorio src y empaquetamos el proyecto.

Luego tomamos un nuevo contenedor que sera encargado de correr nuestra aplicación. Copiamos el jar final desde el contenedor con alias build y lo colocamos en nuestro contenedor final con propiedades extra para poder correr nuestra aplicación. 


Como optimizar este build? 

El build se puede optimizar con solo agregar dos lineas de código en nuestro Dockerfile. Lo primero sera copiar el archivo pom.xml por sí solo y correr mvn package. 
Esto instruye a docker a correr un build de maven, descargar todas las dependencias y crear una capa en el cache de docker con todas las dependencias.
El archivo se ve como sigue.
FROM maven:3.6-jdk-11 as build

WORKDIR /src
ADD pom.xml .
RUN mvn package -DskipTests
# Este paso optimiza los builds hasta que el archivo pom o las dependencias cambien
ADD src src
RUN mvn package -DskipTests

FROM adoptopenjdk:11-jre-hotspot
COPY --from=build /src/target/app.jar /app/app.jar
CMD ["java", "-jar", "/app/app.jar"]
EXPOSE 8080

Una vez que esta capa este en el cache de docker. Cualquier build que siga y comparta él mismo cache ya no necesitara descargar todas las dependencias y solo se enfocara en compilar los archivos dentro del directorio src. 


Espero y este pequeño truco les sirva para optimizar sus proyectos que utilizan maven y docker

jueves, 18 de junio de 2020

De Regreso & Docker

Hola que tal a todos,

Pues como a muchos nos ha pasado en este 2020 y con toda la locura del corona virus (SARS COv2), los proyectos en el trabajo y en la vida personal han disminuido. A Varios meses ya de estar encerrado y con algo de tiempo libre. He decidido re tomar este blog y escribir un poco sobre lo he aprendido durante esta cuarentena. Durante el encierro he estado desarrollando algunos proyectos que me parecen interesantes y que quisiera compartir en una serie de posts. Empezaremos con algunas entradas básicas que serán fundamentales para poder avanzar y entender un poco más sobre el desarrollo en la nube (cloud computing).

Esta entrada se tratara sobre docker y algunas de sus características un poco avanzadas sobre el sistema. Ya llevo varios años trabajando con docker en varias de las compañías en las que he desarrollado proyectos y la verdad es que es una herramienta fácil de entender y una vez que nos acostumbremos a desarrollar con docker no nos podremos imaginar no instalarlo tan pronto obtengamos una nueva computadora.

Una explicación sencilla


Algunos de nosotros todavía nos acordaremos de los viejos tiempos del desarrollo de software (no soy tan antiguo como otros pero sí me han tocado varias transformaciones). Primero se obtenía el código fuente, se modificaba y se probaba localmente. Luego se enviaba a otro grupo para que estos compilaran, lo empaquetaran y lo instalaran en la maquina donde se ejecutaba. Pero qué pasa?, si el sistema operativo, las librerías,  las versiones de las herramientas de compilación, etc son diferentes en cada uno de los diferentes pasos. Esto podría provocar problemas en el desarrollo.

Docker intenta minimizar estos problemas al empaquetar la aplicación y las librerías que se necesitan en un solo contenedor que puede ser ejecutado en una gran variedad de plataformas. Algunas personas mencionan a las Maquinas Virtuales (virtualbox) como un paso intermedio entre maquinas físicas y docker para ejecutar programas. La diferencia es que las maquinas virtuales necesitan un sistema operativo base + librerías para poder ejecutar programas.

Docker agrupa las librerías y herramientas básicas para ejecutar el sistema y tu programa sobre la plataforma docker que corre encima de un el sistema operativo nativo.

Para mas información sobre como instalar docker y mas explicaciones visita https://docs.docker.com/get-docker/ o https://docs.docker.com/get-started/part2/


Un simple ejemplo de como construir una imagen (Dockerfile).


En la actualidad la mayoría de los proyectos utilizan alguna herramienta de construcción como Maven, Npm o Make. Estas herramientas simplifican la compilación, prueba y empaquetamiento del programa. Pero aun tenemos el problema de la distribución es por eso que muchos proyectos agregan el archivo Dockerfile al lado del archivo de proyecto como el pom.xml.

Todos los ejemplos los podemos encontrar en el repositorio: https://github.com/ti3r/demostracion-simple-java-docker

Una vez que los desarrolladores modifican el código es tan fácil como ejecutar para obtener la imagen final:

docker build -t proyecto:latest .

(este comando utiliza el archivo: https://github.com/ti3r/demostracion-simple-java-docker/blob/main/Dockerfile)

Con esta técnica, el proyecto debe de estar compilado, probado y empaquetado para que el resultado final sea agregado a la imagen de docker. Generalmente este paso es realizado en un servidor de Integración Continua (CI), como CircleCI, Jenkins, etc. el cual se encargara de construir la imagen de docker que sera ejecutada.



Un ejemplo un poco mas complejo (Dockerfile multi stage build)


Cómo vemos empaquetar aplicaciones con docker es muy sencillo. Es muy común también que nuevos desarrolladores no tengan las herramientas para construir la aplicación, o que algún servidor de CI tenga versiones diferentes o que haya librerías diferentes o que no tengamos acceso a instalar algunos requerimientos para poder compilar, probar y empaquetar la aplicación. Una manera de resolver estos problemas es utilizar Multi-Stage Docker Builds. Para este ejercicio utilizaremos el archivo:

Podemos ejecutar:

docker build -t proyecto:latest -f Dockerfile.multi .


Una explicación rápida de que es lo que pasa en este archivo.

  1. Definimos un stage utilizando una image base con nómbre "build"
  2. Definimos un directorio donde se copiaran los archivos del proyecto
  3. Copiamos todos los archivos fuente, el archivo pom y el wrapper de maven a ejecutar (para saber mas sobre mvn wrapper puedes leerlo aquí: https://github.com/takari/maven-wrapper)
  4. Ejecutamos maven para que cree el programa final
  5. Definimos la imagen base del programa de resultado
  6. Definimos las etiquetas y directorios de la imagen final 
  7. Copiamos el resultado de la compilación del stage "build" a nuestra imagen final

Utilizar multi-stage builds en docker resuelve varios problemas sobre cómo el preparar y compilar nuestra aplicación final. De esta manera podemos:
  • Estandarizar todas las herramientas necesarias para obtener nuestra aplicación final dentro de nuestro repositorio. 
  • Utilizar diferentes imágenes para compilar y correr nuestro programa reduciendo el tamaño de la imagen final ya que no necesitamos
  • Acelerar el desarrollo del proyecto ya que nuevos desarrolladores no necesitaran instalar nada en el sistema antes de aportar. Solo tener docker, clonar el repositorio y ejecutar los comandos necesarios 



viernes, 11 de diciembre de 2015

Mocking Tests Con Spring Boot, Spock y Gradle

Hola que tal, ya tenia mucho tiempo que no escribía en este blog. Para ser sinceros lo había abandonado ya que cambie de residencia, trabajo varias veces, hobbies y demás. Hacia falta un poco de distracción y enfoque en mi carrera profesional. En las ultimas semanas he tenido un poco de tiempo libre para investigar y desarrollar algunos ejemplos en las tecnologías en las que me he enfocado.

En esta ocasión les tengo un sencillo ejemplo de como utilizar Spock framework para hacer pruebas de unidad en un proyecto. Existen muchas soluciones para las pruebas de unidad como JUnit, NUnit, etc. La ventaja de Spock es que se integra muy bien con diferentes IDEs y Gradle (que ha venido creciendo en adopción como constructor automatizado de proyectos) ya que utiliza ampliamente el lenguaje Groovy. Ademas que apoya al desarrollador a escribir las pruebas de unidad en una forma

En lo particular me he tardado en adoptar el lenguaje groovy y todas las ventajas que este trae pero en cuanto a pruebas de unidad e integración es verdad que ofrece varias ventajas. El código fuente de el proyecto lo pueden encontrar en mi perfil de github y a continuación les ofrezco una pequeña explicación de como esta conformado el proyecto.

En primera es un proyecto gradle de naturaleza mixta entre Java y Groovy y todas las dependencias se pueden encontrar en el archivo build.gradle.

A continuación en el directorio src/main/java/.... encontraran las clases Java Greeting, HelloResource y SpringBootSpockTestApplication. Estas 3 clases sirven para construir una aplicación spring-boot rapida que expondrá un servicio web rest en la url /hello (Si necesitan saber mas sobre spring-boot pueden visitar este link). Como ven hasta aqui es una aplicación muy basica, la finalidad de este proyecto no es realizar la aplicación si no demostrar como hacer pruebas de unidad ya que en la actualidad es una parte muy importante de todo desarrollo de software.

Dentro del directorio src/test/groovy/.... se encuentra una sola clase que es la que contiene todas las pruebas de unidad expresadas en lenguaje spock y las cuales intentare explicar a continuación.


Primero describimos una clase (en este caso SpringBootSpockTestApplicationTests) la cual extiende la clase base Specification de spock. Luego definimos dos objetos compartidos para todas las pruebas (los cuales están marcados por la anotación @Shared). El primero de ConfigurableApplicationContext que es donde tendremos nuestro contexto de spring para poder acceder a beans específicos si es que necesitamos. El segundo de tipo MockMvc la cual utilizaremos para realizar llamadas rest hacia nuestros recursos REST y verificar su funcionamiento.  El método setupSpec() solo prepara estos dos objetos utilizando la conflagración de spring para que estén disponibles para las pruebas.


Luego del setup vienen los métodos de prueba (o feature methods) los cuales están descritos por un titulo (normalmente una explicación de lo que la prueba esta intenta hacer) y dentro los bloques de la prueba ( when , then). Estos bloques permiten describir la prueba de una manera mas explicita y visible para los usuarios u otros programadores. Por ejemplo en estas pruebas solo hacemos una llamada GET utilizando nuestro objeto mockMvc en nuestro bloque When y en nuestro bloque Then verificamos que el resultado de la llamada contenga los valores que requerimos utilizando jsonPath.


Spock se integra muy bien con diferentes ides asi que si este proyecto es abierto en eclipse las pruebas se pueden correr como una jUnit normal y el monitor de resultados nos dara los resultados como normalmente de muestran para junits normales. Ademas al construir nuestro proyecto utilizando gradle, estas pruebas también serán detectadas y desplegadas en nuestro reporte de pruebas.  Un ejemplo seria, al descargar el proyecto y ejecutar el comando
" ./gradle clean build " dentro del directorio del proyecto el archivo build/reports/tests/index.html sera creado con los resultados de las pruebas el cual se vera a algo parecido a la ultima imagen del post.

El mejor lugar para iniciar a entender spock es su pagina de basics la cual explica muy bien como definir pruebas en lenguaje spock. La pagina la pueden encontrar aquí https://code.google.com/p/spock/wiki/SpockBasics








Bueno eso es todo por hoy, espero y este post les sea de ayuda. Espero y seguir escribiendo en el blog mas seguido.

viernes, 26 de julio de 2013

Android 4.3 en Galaxy Nexus (Instalación Manual)

Algunos de ustedes ya sabrán que hace unos días se realizo el evento "Google Breakfast", así llamaron a la pequeña conferencia nada comparada con google I/O pero donde se anunciaron nuevos productos de Google. La nueva nexus 7 (la cual incluira el nuevo android), Google Chromecast, y por supuesto Android 4.3 aun llamado Jelly Bean. Esta nueva versión de Android es una actualización menor al sistema pero que trae interesantes nuevas características. La primera es OpenGL 3.0, luego mejor rendimiento en Bluetooth, y una nueva API para DRM la cual supuesta-mente permitirá mejor calidad en el vídeo. Se dijo que Netflix sera el primero en utilizar este nuevo código en su aplicación pero esperemos y otras apps como youtube o ulu lo hagan también.

Fue una conferencia interesante, si desean ver un resumen de lo que sucedió pueden visitar el siguiente link. Uno de los mejores anuncios fue que las actualizaciones Android 4.3 por OTA ya han comenzado y Galaxy Nexus es uno de los dispositivos que obtendrán esta actualización. Es bueno saber que Google no nos ha olvidado como usuarios, la desventaja es que en ocasiones esta actualización puede tardar hasta semanas enteras en llegar al dispositivo, dependiendo del carrier. Si son como yo, tal vez el tiempo se les haga eterno así que me di a la tarea de actualizar mi dispositivo manualmente y probar esta nueva actualización. Aqui abajo les dejo los pasos para hacerlo. Lo que necesitaran sera el Android SDK y los drivers para galaxy nexus en su computadora (si es que utilizan windows, si son linux users como yo no es necesario preocuparse por los drivers).
1. Descarguen el archivo de actualización y coloquen lo en la carpeta platform-tools dentro del sdk. Este es el link para descargarlo

2. Apaguen el teléfono e inicien en modo recovery con el dispositivo conectado a la pc.
Para iniciar en modo recovery es necesario presionar las dos teclas de volumen y el botón de encendido al mismo tiempo, una vez que inicie el menu con el android este listo pueden usar volumen arriba o abajo para seleccionar "Recovery Mode" y luego presionar la tecla de encendido.

3. Una vez que aparezca el Android con un símbolo de exclamasión es necesario acceder al menú de recovery, presionen las tecla volumen arriba y encendido varias veces hasta que el menú en azul aparezca. Una vez ahí seleccionen "apply update from adb" utilizando la tecla de endendido.

4. Una vez que el teléfono este esperando la actualización tenemos que ejecutar el siguiente comando en una consola:
adb sideload
Si quieren verificar que el teléfono este listo para recibir la actualización antes de ejecutarla pueden escribir el siguiente comando: 
adb devices
Y debe de mostrar el telefono en modo sideload. Algo parecido a esto:
List of devices attached 
01467D551201000E sideload 

5.0 Una vez que la actualización se haya completado solo seleccionamos "reboot" en el menú para que el teléfono se reinicie y poder utilizar la nueva versión de Android en nuestro Galaxy Nexus.

Por el momento no he notado una gran diferencia entre esta nueva versión y la anterior, en teoría el rendimiento debería ser mejor pero hasta el momento no he podido notar la diferencia. La única diferencia visible es la aplicación de la cámara de fotos, la cual ya cuenta con una nueva interfaz y con la opción de timer para tomar las fotografías, esta era una de las opciones que mas quería en la aplicación.

Una de mis sorpresas es que tenia un problema con mi entrada de audífonos y esta quedo arreglada. En la ultima semana el teléfono detectaba que los audífonos estaban conectados aun cuando no lo estaban y no era posible poder escuchar las llamadas por el auricular como normalmente lo hacia. Inclusive des arme el teléfono y reemplace la pieza por una nueva pero ni aun así ayudo en ese tiempo así que creo que era un problema con el software. Muy bien aquí abajo les dejo unas imágenes de como se ve el sistema y en los siguientes días comentare si encuentro diferencias grandes en cuanto al rendimiento o al sistema.

P.D. si desean realizar esta actualización manualmente o esperar por la actualización manual comenten sus ideas en la sección de abajo.

Update: Si tienen problemas con los drivers o el ejecutar comandos en la consola en teoría debe de ser posible aplicar el update desde la memoria interna del teléfono, yo no lo hice así pero esta es otra opción. Lo único que hay que hacer es colocar el archivo de actualización dentro del teléfono y seleccionar "apply update from sdcard" en el menú de recovery.


miércoles, 10 de julio de 2013

Ejemplo Con Action Drawer

Hoy vamos a realizar un pequeño ejemplo de una aplicación con ActionDrawer. La mayoría de las aplicaciones utilizan este componente en la actualidad para desplegar menús de opciones. En un inicio el menú de opciones por defecto fue reemplazado por el Action Bar al aparecer las Tablets y hoy Google recomienda migrar nuestras aplicaciones a utilizar este diseño para proveer una mejor experiencia al usuario; claro que esto no es estrictamente necesario, podemos desarrollar una app sin utilizar ActionDrawers y no habrá ningún problema.
Si aun no identifican que es ActionDrawer, es la barra deslizable que presenta opciones al usuario en alguno de las puntos finales de la pantalla (generalmente el extremo izquierdo). Google+ nos presenta esta barra con las opciones de fotos, comunidades, etc.

Muy bien manos a la obra, lo primero que aremos es crear un proyecto de Android por defecto. Esto nos debe de crear una actividad principal y un layout para nuestra actividad. Generalmente el nodo raíz de este layout es un LinearLayout o RelativeLayout (o lo que hayamos especificado por defecto), es aquí donde viene el primer cambio. El nodo raíz de  nuestro xml ahora sera un "android.support.v4.widget.DrawerLayout"; esta vista es dibujada de la siguiente manera. El primero nodo hijo sera el contenido que sera desplegado en la pantalla y el segundo nodo debe de ser de tipo "ListView" que sera el que desplegara la lista de opciones. En esta aplicacion de prueba nuestro main_layout.xml se vera de la siguiente manera:



Básicamente lo que este layout describe es DrawerLayout con id "main_act_drawer" como principal; este contiene un primer hijo de tipo FrameLayout con id "content_frame" y un segundo nodo de tipo ListView con id "left_drawer".  Ya habíamos dicho que el primer nodo dentro de DrawerLayout sera lo que se desplegara en pantalla, en este caso FrameLayout lo vamos a utilizar para desplegar un mensaje por defecto (TextView contenido dentro) y cuando el usuario seleccione algo del menú el contenido sera reemplazado por un fragmento definido.
Nota: Es importante resaltar que layout_height & layout_width de la mayoría de las vistas están definidas con constantes, esto bloquea a AndroidStudio de desplegar una vista previa de la pantalla pero al momento de ejecutar la aplicación esta corre sin ningún problema. 

El ListView (left_drawer) lo utilizaremos para desplegar las opciones en nuestro ActionDrawer y por lo tanto necesitamos crear un adaptador que contenga los valores para nuestras opciones. Por lo tanto agregaremos a nuestro archivo strings.xml los siguientes elementos:
El primero es la lista de opciones para nuestro menú el segundo es una lista de colores que definen el valor del color correspondiente en valor hexadecimal. AndroidStudio nos presenta el valor del color en un recuadro en la barra lateral; este es una opción no disponible anteriormente en eclipse ADT y que me parece es un poco cool. 

Ahora escribiremos un poco de código para iniciar correctamente nuestras opciones ya que si no el ActionDrawer no sera desplegado en nuestra aplicación por que no contiene ninguna opción. Así que escribimos el siguiente código en nuestra actividad principal.
En simples palabras una vez que establezcamos el layout de nuestra actividad, llamaremos el método prepareActionDrawer para efectivamente iniciar nuestro menú. Lo primero que hacemos es retraer las vistas de nuestro layout con findViewById. Luego creamos un ArrayAdapter utilizando el arreglo que definimos en strings.xml (main_act_drawer_opts) y lo establecemos a nuestra lista. Luego podemos ver que establecemos un nuevo OnItemClickListener en nuestra lista, esta clase sera la encargada de hacer el  cambio de fragmentos en nuestra vista contenedora así que revisaremos esta clase con mas detalle luego. Al final de nuestro método creamos un nuevo objeto ActionBarDrawerToggle que estará encargado de abrir y cerrar el action drawer cuando demos clic en el icono de nuestra app (parte superior izquierda). Es por esto que nuestra primera linea en el método es setDisplayHomeAsUpEnabled(true) para que este botón aparezca en nuestra barra.

El ultimo código que agregaremos en nuestra actividad principal sera sobrescribir el método onOptionsItemSelected para que nuestro objeto ActionBarDrawerToggle detecte si una de las opciones del menú ha sido seleccionada y el drawer se cierre. El código se ve de la siguiente manera.

La parte final sera crear la clase encargada de manejar el contenido de nuestra aplicación "DrawerClickListener", esta clase sera la encargada de actualizar el fragmento que desplegara el contenido por cada una de las opciones que el usuario seleccione. Para esto necesitamos fragmentos que serán colocados en nuestro "content_frame"; aquí vamos a hacer uso de una vieja clase PlainColorFragment del proyecto anterior view_pager_test (si no recuerdan este proyecto visiten los posts de Ejemplos con View Pager 1,2, 3 ). El codigo de esta clase se ve como se muestra aqui abajo:
En el constructor de la clase necesitamos 3 referencias, la primera a un FragmentManager que sera el encargado de cambiar los fragmentos en el contenido (proviene del fragment manager de la actividad principal). El segundo es la referencia a nuestro DrawerLayout el cual nos permitirá manipular el layout y el tercero nuestra lista de opciones en el Drawer para poder cerrarla.  Ademas de esto creamos la referencia a los valores de los colores que almacenamos en strings.xml utilizando getResources() desde una de nuestras vistas.
Luego de nuestro constructor tenemos el evento importante onItemClick, este es el evento que se ejecuta cada vez que una opción de nuestro ActionDrawer es seleccionada. Lo primero que hacemos es seleccionar el color de nuestro arreglo basado en el valor del indice que nos manda la selección. Luego mandamos cerrar la lista de nuestro drawer con el método closeDrawer de nuestro DrawerLayout para que el usuario vea el cambio en el contenido. Por ultimo utilizaremos nuestra clase PlainColorFragment para crear instancias del fragmento que se desplegara basándonos en el color que se ha seleccionado; iniciamos una nueva transacción en nuestro FragmentManager y reemplazamos el contenido de content_frame, con el fragmento que acabamos de crear y le ponemos el nombre del color que seleccionamos. Al final hacemos commit en la transacción para que sea aceptada.

En los screens que se muestran abajo les muestro como se ve la app ya terminada y como siempre el código esta disponible para el que así lo desee en mi perfil de github. Espero y este articulo les sea de utilidad ya que la mayoría de las aplicaciones ahora están desplegando Drawers como este.

Update: Si quieren descargar la aplicación funcionando desde play store pueden hacerlo con este link. Si lo hacen se los agradecería ya que ayudarían a que continué desarrollando para android. 
https://play.google.com/store/apps/details?id=org.blanco.android.actiondrawerexample

Saludos a todos

miércoles, 3 de julio de 2013

Ejemplo de Comerciales

Hola que tal, un saludo a todos los lectores. Una disculpa por estar ausente durante bastante tiempo, varias cosas han pasado que me han impedido dedicarle un espacio al blog. Una de ellas es que aun me estoy adaptando a Android Studio (el nuevo IDE para Android que esta basado en IntelliJ). En esta ocasión les quiero compartir un pequeño ejemplo de como monetizar una aplicación utilizando un framework llamado TapContext. En la actualidad existen varias alternativas de monetizar una aplicación para Android, ademas de AddMob el framework por defecto de Google, un developer puede añadir el la librería de su preferencia para desplegar comerciales y comenzar a ganar dinero (a eso me refiero con monetizar).

Escogí la librería de TapContext por que es muy sencillo de utilizar y configurar; aun cuando no te da mucha libertad en la configuración; es un buen punto de partida para comenzar a trabajar con comerciales. Lo primero que debemos de hacer es registrar una cuenta en https://www.tapcontext.com/ y descargar la librería del SDK. Una vez que tengamos la descarga lo único que debemos de hacer es colocar el jar en la carpeta lib de nuestro proyecto y el archivo tapcontext_notification_layout.xml bajo src/main/res/layout. Una vez que realicemos esto es necesario hacer los vínculos y configuraciones necesarias para llamar comerciales en nuestro código.

El primer vinculo es en realidad para que podamos comenzar a utilizar la librería sin que Android Studio nos muestre errores en el código; lo que tenemos que hacer es agregar la librería al classpath de gradle (recuerden que el nuevo sistema de compilación y construcción de Android esta basado en Gradle). Para esto editamos el archivo build.gradle dentro de nuestra carpeta del proyecto y agregamos la siguiente linea dentro del elemento dependencies "compile files('libs/TapContext_2.1.jar')". El resultado final de este elemento se debería de ver algo similar a:

dependencies {
    compile files('libs/android-support-v4.jar')
    compile files('libs/TapContext_2.1.jar')
}

Una vez que hemos corregido nuestras dependencias podemos empezar a configurar nuestro contexto para comerciales. Tenemos que agregar las siguientes lineas a nuestro archivo manifest (AndroidManifest.xml).

Dentro de el nodo Application agregamos:



Solo quiero aclarar que la parte que dice ***key*** tiene que ser reemplazada por la clave que obtuvieron cuando se registraron para el servicio. Esta clave estará disponible en su perfil. Lo que agregamos solo fue la actividad que sera lanzada cuando se desplieguen los comerciales y un servicio que estará escuchando para mantener los comerciales y las estadísticas.

Solo con estas configuraciones ya podemos iniciar a mostrar comerciales en nuestro código. Como las imágenes son un poco grandes yo opino que la mejor manera de mostrarlos es cuando nuestra aplicación inicie (o cuando algún evento importante termine), para eso agregamos el siguiente código en nuestra actividad.

@Override
    protected void onStart() {
        TapContextSDK adsContext = new TapContextSDK(getApplicationContext());
        adsContext.initialize();
        adsContext.showAd();
        super.onStart();
    }

Listo solo con este código podremos crear una aplicación que despliegue comerciales al iniciar. TapContext es solo uno de los muchos frameworks par desplegar comerciales que existen. En mi opinión no es el mejor pero si uno de los mas sencillos de usar, cuenta con un dashboard decente para revisar tus publicaciones, avance de ganancias, etc. Ademas de que su soporte a usuarios es bueno. Abajo les dejo pantallas de como se ven los comerciales dentro de la aplicación y como siempre el código fuente esta disponible en mi GitHub.

Saludos y gracias por leer.

viernes, 26 de abril de 2013

Ejemplo con View Pager super Extendido (Animación en Pager)

Hola que tal, en esta ocasión les quiero compartir otro ejemplo con ViewPager. Voy a extender un poco mas los ejemplos mostrados anteriormente en otros posts para actualizar y explicar un poco mas acerca del funcionamiento del ViewPager y los Fragmentos. Gracias a todos aquellos que escribieron comentarios y preguntas por tomarse el tiempo de leer el blog y practicar con estos sencillos ejemplos.

Aun y cuando los Fragmentos fueron introducidos a Android desde API 11 (Android 3.0 HoneyComb), han evolucionado y cambiado para hacerse mas dinámicos y permitir mucha mas flexibilidad en la interacción con el usuario. Un fragmento es básicamente una mini ejecución  que toma parte de la pantalla de nuestra actividad y cuenta con su propio ciclo de vida, eventos, etc. Inicio con una pequeña explicación sobre fragmentos por que si recuerdan en ejemplos anteriores comenzamos creando un fragmento el cual sera un poco distinto para cada una de las paginas de nuestro ViewPager. El código que prepare es el siguiente:


public class PlainColorFragment extends Fragment {
  private static final String PLAIN_COLOR_FRAG_ARG_COLOR = "color";
  int color = Color.GREEN;
  View view = null;
  AnalogClock clock = null;
  public static PlainColorFragment newInstance(int color) {
    PlainColorFragment frag = new PlainColorFragment();
    Bundle frag1Args = new Bundle();
    frag1Args.putInt(PLAIN_COLOR_FRAG_ARG_COLOR, color);
    frag.setArguments(frag1Args);
    frag.setRetainInstance(true);
    return frag;
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.color = (getArguments() != null) ? getArguments().getInt(PLAIN_COLOR_FRAG_ARG_COLOR) : Color.GRAY;
  }
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.color_layout, container, false);
    clock = (AnalogClock) view.findViewById(R.id.analogClock1);
    clock.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        vanishClock();
      }
    });
    view.setBackgroundColor(color);
    return view;
  }
  public void vanishClock() {
    if (clock.getAlpha() < 0.4f)
      clock.setAlpha(1.0f);
    else
      clock.setAlpha(clock.getAlpha() - .2f);
  }
}

A partir de Android 4.0 y la revisión de la librería de soporte 12. Es necesario que nuestros fragmentos tengan un constructor por defecto (sin parámetros) para que puedan ser destruidos y reconstruidos por el FragmentManager. Por lo tanto en nuestro código creamos un método estático (newInstance) que nos ayudara a crear instancias de nuestro fragmento basado en el color que pasemos como parámetro. Y ya que cuando un fragmento es creado su método onCreate es ejecutado podremos retraer el color de nuestro fragmento por el método getArguments(). Pueden notar que en nuestro método newInstance asignamos estos parámetros a nuestra nueva instancia; el FragmentManager conservara estos parámetros por nosotros y si es necesario destruir nuestro fragmento por baja memoria o algún otro factor, los parámetros serán guardados para estar disponibles cuando nuestro fragmento se reconstruya. En el código también se puede observar que en el método onCreateView; ademas de asignar nuestro color de fondo; inflamos un layout contenido en una definición XML el cual le dará cuerpo a nuestro fragmento. Es importante notar que el metodo onCreateView es ejecutado no solo una vez si no varias veces, en ocasiones es necesario por cuestiones de recurso destruir vistas y reconstruirlas mas tarde cuando estos recursos esten disponibles; pero eso lo explicare mas delante. Ya con nuestra vista extendida, lo que hacemos es asignar nuestro identificador clock al componente reloj que se encuentra dentro de nuestro xml y asignarle un pequeño método (vanishClock) a su evento click. Esto ira desvaneciendo el reloj por cada clic que el usuario haga sobre el. Aquí abajo les dejo la definicion XML de la vista que inflamos para nuestro fragmento.



Muy bien ahora iremos con nuestra actividad principal, el codigo se ve como el que sigue:
Lo que podemos ver aquí es que tenemos dos propiedades, nuestro ViewPager (pager) y nuestro PageChangeListener (pageChangeListener). View pager es el encargado de cambiar de pagina cada vez que el usuario deslice el dedo en nuestra actividad y la clase PageChangeListener, la utilizaremos para algunas operaciones auxiliares las cuales explicare un poco mas adelante. Lo importante viene en el método onCreate de nuestra actividad; primero establecemos nuestra vista (R.layout.main), la cual contiene en su definición un ViewPager con el id pager. La definicion de este contenido lo pondre un poco mas abajo. Luego creamos un objeto MyFragmentPagerAdapter (una clase definida por nosotros) y agregamos 3 fragmentos de creamos manualmente también. Noten que para nuestros fragmentos mandamos llamar al método estático que preparamos (newInstance) con 3 distintos colores como parámetros. Luego asignamos a nuestro ViewPager el pageChangeListener, el adaptador que acabamos de preparar y un nuevo transformador que también explicare un poco mas tarde. Y eso es todo por el momento para nuestra actividad principal. Ahora les dejo el layout que asignamos para esta actividad
Como pueden observar no es algo muy complejo solo un Text View para mantener un titulo en nuestra actividad en todo momento y nuestra clase importante, nuestro ViewPager. Pero como vimos en el código nuestro ViewPager solo es asignado con varios recursos, en realidad el ViewPager es el conector entre nuestros distintas clases las cuales en realidad son las que hacen el trabajo pesado. Arriba pudimos ver que tenemos una clase llamada MyFragmentPageAdapter y a la cual se agregamos nuestros 3 fragmentos que creamos con el método addFragment; por lo tanto vamos a revisar esta clase.
Esta clase extiende de la clase abstracta FragmentPageAdapter, la cual esta cargo de manejar los fragmentos que estarán disponibles para nuestro ViewPager. Cada vez que el usuario cambie de pagina deslizando el dedo el ViewPager solicitara al adaptador que le regrese el fragmento correspondiente a la pagina que el usuario esta cambiando hasta que lleguemos a nuestro getCount(), cuando ya no haya mas paginas disponibles el ViewPager no permitirá al usuario seguir cambiando de pagina hacia adelante. Como ven la implementacion es sencilla. Solo tenemos una lista de fragmentos y cada vez que vayamos agregando un nuevo fragmento al adaptador este se agregara a nuestra lista. Cuando el Pager solicite una pagina en especifico con el método getItem, nosotros regresaremos el fragmento correspondiente de la lista y el getCount sera igual al tamaño de nuestra lista.

Luego tenemos nuestro PageChangeListener
Esta clase es muy sencilla, cuando un evento de cambio de pagina suceda en nuestro ViewPager, esta clase sera llamada y en la cual podemos interceptar información valiosa. En nuestro caso solo tenemos una propiedad currentIndex, la cual sera asignada cada vez que una pagina sea seleccionada (onPageSelected) y la cual expondremos por medio de un método publico getCurrentIndex. La finalidad de esta clase la podrán ver mas delante. Lo ultimo que asignamos a nuestro ViewPager es un nuevo objeto PageTransformer con el método setPageTransformer. Esta clase lo que hará sera dar una buena animación al cambio de pagina. Una nota personal aquí es que yo no soy muy bueno para diseñar animaciones y esta clase la tome de uno de los ejemplos de Google solo la modifique un poco así que no pondré el código, este lo pueden obtener en mi github junto con el código fuente.  Así que con esto ya tenemos un muy buen ejemplo casi igual al que teníamos anteriormente, pueden ejecutar la aplicación y podrán ver como al deslizar de pagina los distintos fragmentos de colores van apareciendo y al dar clic en el reloj este se va desvaneciendo poco a poco.




Pero les daré una pista, ya habíamos dicho que el método onCreateView de los fragmentos es llamado en varias ocasiones. Así que que es lo que tal vez ya habrán notado que si desvanecen el reloj hasta cierto punto y cambian de paginas varias veces, el reloj que anteriormente estaba desvanecido ha vuelto a la normalidad. Esto sucede ya que cuando cambiamos de pagina el sistema reclama la memoria de las vistas que están ocultas y estas son destruidas. El cuando esto sucederá depende del sistema, de los recursos disponibles, etc., tal vez en ciertos dispositivos poderosos como el S4 esto no pase, pero es mejor estar precavidos y dar a nuestros usuarios la mejor experiencia. Así que lo que haremos sera sobre escribir el método onViewDestroyed para salvar el estado de nuestro reloj y así poder re-establecerlo al momento de que esta vista sea creada de nuevo. Lo que haremos sera agregar un poco de código a nuestro fragmento como el que sigue.

Lo que hicimos es crear dos propiedades un Bundle (viewRecreateState) que sera donde guardaremos nuestro estado. Recuerden que lo que es destruido es nuestra vista pero las propiedades del fragmento se quedan intactas hasta que el fragmento sea destruido también si es que esto ocurre. Entonces crearemos una nombre estático el cual utilizaremos como indice en nuestro bundle y el método restoreClockState que sera en cargado de establecer el alpha del reloj si es que tenemos este valor guardado en nuestras preferencias. Creo que el método onDestroyView es muy fácil de entender, solo guardaremos el alpha de nuestro reloj antes de que la vista sea destruida. Por lo tanto lo único que tenemos que hacer ahora es llamar a nuestro método restoreClockState dentro de onCreateView para que si la vista fue destruida anteriormente esta vuelva al estado anterior cuando es recreada. Ahora nuestro método se vera así:

Y ya para terminar agregaremos los métodos necesarios para seguir el mismo funcionamiento de el articulo anterior. Esto es crear un menu para lanzar una animación en la pagina actual cuando el usuario haga clic en el item. Esto muestra de manera sencilla como interactuar con los fragmentos desde un agente externo. Recuerdan que teníamos un listener (PageChangeListener) en nuestro pager que guardaba la pagina actual? Y agregaremos a cada fragmento tiene un método publico startAnimationClock que animara el reloj y el cual sera llamado para animar el reloj interno. El codigo se ve asi.

Y en nuestra actividad principal agregamos:


Así que al final tendremos nuestra aplicación terminada y sin importar si cambiamos de pagina mil veces, mientras nuestro fragmento este en el sistema nuestra aplicación siempre presentaran una interfaz consistente a nuestros usuarios. Bueno como siempre, el código completo de este ejemplo lo pueden encontrar en mi perfil de github en esta tag del repositorio. Y ya saben si tienen alguna duda, sugerencia y/o comentario no duden en comentar o escribir un correo. Una disculpa por el post tan largo pero trate de explicarme lo mejor posible.
Saludos a todos.


 

miércoles, 10 de abril de 2013

Ejemplo con Layout Animation Y Android

Hola que tal, en esta ocasión quiero compartir un pequeño ejemplo sobre como Animar fácilmente vistas en un layout usando Android. Este pequeño ejemplo esta basado en el articulo que publico Chet Haase en Androide Dev Bites. En realidad el ejemplo es muy sencillo y tratare de explicarlo lo mejor posible extendiendo un poco mas para hacerlo un poco mas atractivo. Con esto espero poder hacer una serie de artículos acerca de animaciones en Android.

Con la entrada de la android API versión 11 (Android 3.0) la clase LayoutTransition nos permite ejecutar animaciones cuando haya algun cambio en el layout de un contenedor. Como puede ser un LinearLayout, RelativeLayout, etc.

Muy bien vayamos al ejemplo. Lo primero que tenemos es un simple layout con dos botones y un contenedor. El contenido de nuestro main_layout xml es como el que sigue:


Es muy simple, nuestro main layout es LinearLayout con orientación vertical. Luego un botón para agregar una vista (Add View), un botón para remover una vista (Remove View) y al final otro LinearLayout el cual tomara el resto de la pantalla para el también con orientación vertical. El punto interesante en este ultimo contenedor es la propiedad android:animateLayoutChanges="true"; esta propiedad es la que nos dirá que cada vez que haya un cambio en este layout estos cambios deberán de animarse. Por defecto solo los cambios de entrada y salida de vistas serán animadas pero eso lo arreglaremos mas tarde.

Ahora si en nuestra actividad principal


public class MainActivity extends Activity {
LinearLayout container = null;
private static LayoutParams mParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
   ViewGroup.LayoutParams.WRAP_CONTENT);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
container = (LinearLayout) findViewById(R.id.layout_container);
}
public void btnAddViewClicked(View view){
 Button btn = new Button(view.getContext());
 btn.setLayoutParams(mParams); btn.setText("Useless Button");
container.addView(btn,0);
}
public void btnRemoveViewClicked(View view){
if (container != null && container.getChildCount() > 0){
container.removeViewAt(
(int)(Math.random()  * (container.getChildCount())) 
);
}else{
Toast.makeText(view.getContext(), "No views to remove", Toast.LENGTH_LONG).show();
}
}
}

Lo primero que haremos en onCreate sera establecer nuestro xml como el contenido y luego vamos a retraer el contenedor que definimos para almacenarlo en la variable container. Este objeto container ya tiene las animaciones establecidas. Luego los dos métodos para agregar y eliminar vistas, como lo definimos en nuestro xml cuando el botón Add View es presionado el metodo btnAddViewClicked se ejecuta; en este método lo que haremos sera crear un nuevo botón  asignarle las propiedades y el texto correspondiente y luego agregarlo al contenedor con el método container.addView.

De la misma manera el método btnRemoveViewClicked sera ejecutado cuando el botón Remove View es presionado; este método lo único que se encarga es de remover una vista del contenedor de una posición alternativa si el contenedor ni tiene ninguna vista asociada (esto es su childCount no es mayor que 4) simplemente mostramos un mensaje con Toast.

Y eso es todo como pueden ver no tenemos ningún código extra sobre animaciones, efectos, etc. El sistema se encargara de hacer las animaciones automáticamente al momento de que se agreguen y remuevan vistas. Como pueden ver es un ejemplo muy sencillo pero nos ayudara a darle un poco mas de presentación a nuestras aplicaciones.

Aquí abajo les dejo una muestra de como se comporta la aplicación y en un post futuro veremos como extender esta aplicación para hacerla mas dinámica. Como siempre pueden obtener el codigo fuente de este y otros proyectos visitando mi perfil de github.

P.S estoy extrayendo el vídeo para que vean como se ve pero aun estoy probando distintas apps para screencast. En cuanto lo tenga actualizo el post. (No creo que sea de mucha ayuda si subo fotos :P). Saludos

Update: Aqui les dejo el video, no muy buena calidad pero pasa.

martes, 5 de marzo de 2013

Opciones de Desarrollador en Android Jellybean (4.2)

Hola que tal a todos, este es un pequeño comentario sobre la ultima actualización que se envió a Android Jelly-Bean (4.2). Puede ser que ya lo hayan notado pero a partir de la ultima actualización de Jelly Bean  el menú de opciones de desarrollador no se encuentra disponible en el menú configuraciones. Google consolido todas las opciones de desarrollador dentro de una sección en el menú de configuraciones, la mayoría de las veces lo único que realizábamos en este menú es activar o desactivar el USB Debugging para que al conectar el cable USB el teléfono nos mostraba una carita de Android en la barra de notificaciones (hace mas que eso pero no quiero hacerla larga).
Para poder activar este menú de nuevo en la nueva versión de Android es necesario decirle al teléfono que su usuario es un desarrollador, hay que ir al menú de Configuraciones -> Acerca del Teléfono -> Numero de Build. Hay que tocar varias veces este ítem después de varias ocasiones veremos un mensaje diciendo "estas a X clicks de ser desarrollador", luego de sobrepasar este numero el menu se hará visible en las configuraciones donde anteriormente estaba.
Esta movida fue publicada por google ya que en los teléfonos mas comerciales como el Galaxy S3 o One X, etc el usuario común no quiere ver este menú. Por lo tanto nuevos teléfonos con Jelly Bean no desplegaran este menú hasta que sean activados como desarrollador. He probado esta opción en mi Nexus Galaxy, Galaxy S4 y HTC One X+ y en todos me ha funcionado. Así que si eres desarrollador y extrañas este menú en tu dispositivo ya sabes el por que y como volver a activarlo.

Saludos a todos

lunes, 4 de marzo de 2013

Ejemplo Con ViewPager Extendido

En esta ocasión vamos a continuar un poco mas con ejemplos de Android. Hace algún tiempo publique un post sobre como utilizar ViewPager en Android y hace algunos días recibí una pregunta de un lector sobre como hacer cosas mas avanzadas en el View Pager. Para recordar un poco aquel ejemplo desplegaba dos vistas similares (el reloj de Android) pero con un color de fondo diferente. Al deslizar la vista hacia la derecha o izquierda el View Pager cambiaba la vista a desplegar en pantalla y se puede observar el cambio en el color de fondo. La pregunta de Oscar Sanchez (gracias por leer el blog) es, como acceder al reloj dentro de cada uno de los fragmentos y realizar operaciones con el ?.

Bueno en Android como en casi todas las plataformas existen varias maneras de hacer las cosas, solo es cuestión de seleccionar la que mas te guste y analizar los pros y contras. Así que para contestar esta pregunta la primera aproximación que utilizaremos sera el manejo interno.  Como ya habíamos visto en nuestro ejemplo anterior habíamos creado un PageAdapter que nos manejaba los diferentes fragmentos que agregábamos en una lista y añadiamos  3 fragmentos iguales pero con diferente color de fondo. Como la documentación de Android lo dice, un fragmento es una poción de una actividad que cuenta con su propio ciclo de vida y espacio para dibujar vistas. Por lo tanto en nuestro fragmento podemos manejar nuestras vistas y eventos internamente. Entonces vamos a extender nuestra clase fragmento para que se vea de esta manera.


public class PlainColorFragment extends Fragment {

int color = Color.GREEN;
View view = null;
AnalogClock clock = null;
public PlainColorFragment(int color){
this.color = color;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.color_layout, null); 
clock = (AnalogClock) view.findViewById(R.id.analogClock1);
clock.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startAnimationOnClock();
}
});
view.setBackgroundColor(this.color);
return view; 
}
public void startAnimationOnClock(){
Animation anim = 
AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
clock.startAnimation(anim);
}
}

Lo que hicimos, es simplemente tener una variable que apunte a nuestro AnalogClock llamada clock y en el evento onCreateView asignar esa variable a la vista analogClock1 que se encuentra dentro de nuestro layout. Y ya con nuestra variable clock le asignamos un evento OnClickListener para que cuando el usuario toque la pantalla una simple animación se ejecute, esto es llamar al método startAnimationOnClock ( vean que el método es publico y visible para otras clases, por que luego lo usaremos para otras cosas). Ahora si, al modificar nuestra aplicación previa de esta manera veremos al tocar el reloj de cualquier fragmento seleccionado la animación se ejecutara. 

Nuestra segunda aproximación, en algunas ocasiones es necesario mandar una señal desde fuera de nuestros fragmentos hacia el interior para ejecutar ciertas instrucciones; como por ejemplo la selección de algún ítem del menú o algún otro evento externo . En esta ocasión, haremos que la animación del reloj del fragmento seleccionado se ejecute cuando se seleccione desde el menú. Lo primero que tendríamos que hacer es saber cual fragmento es el que esta actualmente seleccionado; cual reloj de los varios disponibles tendremos que animar para que el usuario lo vea (no tendría caso animar un reloj que este invisible para el usuario, obvias razones). Por lo tanto crearemos una clase que nos guarde el indice del fragmento que el usuario selecciona. La clase se ve de esta manera:


public class PageChangeListener implements OnPageChangeListener {
int currentIndex = 0;
@Override
public void onPageScrollStateChanged(int arg0) {
//Do Nothing
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
//No Nothing
}
@Override
public void onPageSelected(int arg0) {
currentIndex = arg0;
}
public int getCurrentIndex() {
return currentIndex;
}
}


Hace nada, nomas que guardar el numero de indice de la pagina seleccionada en una variable y exponerla por medio de un getter. Esta clase se va a relacionar con el ViewPager con el método setOnPageChangeListener para que cada vez que se haga un cambio de pagina el indice sea almacenado en nuestra variable currentIndex. Y por ultimo en nuestra actividad principal agregaremos métodos para que cuando el botón del menú sea presionado el fragmento visible sea retraído desde nuestro Adapter y llamar al metodo startAnimationOnClock (es por esto que nuestro método es públicamente visible). Asi que nuestra actividad principal se ve de esta manera: 


public class MainActivity extends FragmentActivity {
ViewPager pager = null;
PageChangeListener pageChangeListener = null;
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        pager = (ViewPager) findViewById(R.id.pager);
        
        MyFragmentPagerAdapter adapter = 
        new MyFragmentPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new PlainColorFragment(Color.RED));
        adapter.addFragment(new PlainColorFragment(Color.GREEN));
        adapter.addFragment(new PlainColorFragment(Color.BLUE));
        pageChangeListener = new PageChangeListener();
        pager.setOnPageChangeListener(pageChangeListener);
        pager.setAdapter(adapter);
    }
        private void startAnimationOnCurrentPage(){
        MyFragmentPagerAdapter adapter =  
         (MyFragmentPagerAdapter) pager.getAdapter();
        PlainColorFragment fragment = 
    (PlainColorFragment) adapter.getItem(pageChangeListener.getCurrentIndex());
        fragment.startAnimationOnClock();
        }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.main_menu_start_anim_current_item:
startAnimationOnCurrentPage();
default:
return super.onOptionsItemSelected(item);
}
}    
}

El método importante en esta actividad es startAnimationOnCurrentPage, ya que dentro de el retraemos nuestro adaptador y utilizamos el indice de nuestro pageChangeListener para así poder obtener el fragmento que esta siendo desplegado al usuario. Una vez que tenemos nuestro fragmento lo único que hacemos es llamar startAnimationOnClock() para que la animación en el reloj sea ejecutada. De esta manera logramos propagar un evento ocurrido en el menú de nuestra actividad hacia dentro de las vistas localizadas dentro de nuestro ViewPager.

En esta ocasión vimos como ejecutar una simple operación de animación en la pagina actual de nuestro ViewPager pero en su lugar podríamos  realizar cualquier otro tipo de operación. Retraer las vistas internas, hacerlas invisibles, eliminarlas, cambiarles colores, fondos, etc. Este pequeño post es simplemente para ejemplificar un poco mas como trabajar con ViewPagers en Android. 

Espero y el ejemplo les sea de utilidad y como siempre, el código fuente esta a su disposición en mi pagina de github https://github.com/ti3r/view_pager_test. Pueden descargar, revisar y utilizar el código a su conveniencia. Si este post les gusto por favor dejen sus comentarios, compartan el blog o escriban un e-mail o comentario con dudas  o recomendaciones para poder mejorar este espacio.

Un Saludo a todos y gracias por leer.