Implementando Un On Boarding Slider de una Forma Simple Usando ViewPager2 en Android

Carlos Daniel
Droid LATAM
Published in
4 min readApr 30, 2020

Esta corresponde a una traducción de “A Simple Way To Implement An On Boarding Slider Using ViewPager2 in Android”

Bueno, el nuevo API de ViewPager2 (lanzado oficialmente a fines de 2019) nos permite aprovechar su forma simple de uso para implementar una pantalla de On Boarding usando solamente 4 clases sencillas y muy poco código. Como muchos lo saben, ViewPager2 reemplaza el antiguo API de ViewPager (que ahora mismo ya no recibe ningún soporte de desarrollo activo) y nos ofrece nuevas características tales como soporte RTL (right to left) y DiffUtils (pues es implementado sobre RecyclerView) entre otras. Más detalles y comparación con ViewPager aquí en la documentación oficial en DAC.

Implementando Una Pantalla Swipeable Básica

La forma más simple de ver esto trabajando is creando una pantalla de on boarding, en la cual dejamos saber al usuario información importante de la aplicación mientras se desliza y navega entre diferentes pantallas, pero al final es realmente un solo fragment.

Esta es la aplicación que vamos a implementar:

On Boarding Slider

Empecemos creando un nuevo proyecto con una Actividad vacía y agregamos las dependencias de ViewPager2 y Glide (que usaremos para cargar las imágenes que usaremos de forma asíncrona):

La aplicación presenta un solo Fragment dentro de OnBoardActivity, y la forma en que se hace visible es a través del ViewPager2, que a su vez usa un FragmentStateAdapter. Y aquí es donde está la clave, veamos cómo …

El layout de on_boarding_activity como puede verse, usa un Widget de ViewPager2 cubriendo toda la pantalla. Además, usando Constraint Layout seteamos los botones de forma genérica en su posición, los círculos indicadores y el texto inferior en la parte baja de la pantalla. Ahora vemos que el contenido deslizable estará ubicado en el ViewPager.

Para lograrlo, necesitamos primero crear un custom FragmentStateAdapter, para enlazar el widget del pager y que requiere dos parámetros. Una referencia a la Activity que alberga el adapter y un entero que le dice al adapter el número de elementos que mostrará. También necesitamos sobre escribir los métodos getItemCount() y createFragment(). El primero le dice al adapter el número de ítems del slider y el segundo permite crear una instancia de un Fragment para una posición particular:

Ahora, el layout del fragmento luce así (una imagen y algunos textos informativos):

La clase OnBoardingFragment en la que enlazamos toda la data de cada una de las páginas del pager luciría así. Debemos tener en cuenta que en este ejemplo en particular tomamos toda la información a mostrar localmente desde los resources de strings y el folder raw, pero esto puede escalarse a otros escenarios para ser obtenida desde un endpoint (API service) en la nube o una base de datos local.

Lo más importante de la clase Fragment anterior es saber cómo podemos obtenerla posición desde el adapter, para pasarlo al fragmento como un parámetro en el bundle y así ser usado para sacar la data desde los resources. Sí, así es como enlazamos el adapter y el fragmento.

Ahora, para enlazar el Fragment con el Activity a través del ViewPager, simplemente necesitamos escuchar por cada cambio de página. ViewPager2 usa una clase abstracta, OnPageChangeCallback, que provee una implementación vacía para tres métodos. De esta manera, solamente necesitamos sobre escribir los métodos que necesitamos, y para este caso es el onPageSelected().

Creamos entonces un objeto de tipo onBoardingPageChangeCallback que necesita registrarse en el ViewPager (binding.onBoardingViewPager.registerOnPageChangeCallback) y para evitar leaks de memoria, debe ser deregistrado cuando el Activity se destruye (binding.onBoardingViewPager.unregisterOnPageChangeCallback).

El método local updateCircleMarker() tiene la responsabilidad de enlazar la posición del pager con el indicador visual para distinguir cada que hacemos slide de una pantalla.

UI Testing el ViewPager

Bueno, esta parte es fácil porque no requiere nada diferente a hacer uso del método swipe() del ActionView para ejecutar un slide. Todos los test sobre OnBoardingActivity serán lanzados dentro de un ActivityScenarioRule<>, que no es más que una regla que lanza una activity en particular antes que el test comience y la cierra cuando el test termina. Para ello necesitamos adicionar un par de dependencias al archivo build.gradle:

Después de sincronizar y crear un objeto ActivityScenarioRule dentro del archivo de test (en androidTest), es posible que aparezca este mensaje de error:

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6

Éste puede ser fácil y rápidamente corregido adicionando esta línea en alrchivo build.gradle dentro del bloque android{…} para decirle al compilador de Kotlin en Android Studio que use una versión en particular del JDK:

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}

Finalmente, el código de nuestro test luce así:

… y esto es todo, este es el repo con el ejemplo que pueden usar y compartir con quien quieran. También, tengan en cuenta que este es uno de los muchos usos que podríamos darle al API de ViewPager2, pues también pueden personalizar su uso ya sea implementando swipe vertical, o agregar un TabLayout o incluso soportar RTL.

Recuerden pasarse por mi perfil para encontrar más contenido técnico de Android:

--

--

Carlos Daniel
Droid LATAM

Android & Flutter Developer. GDE for Android & Mobile Engineer.