Android TabLayout y ViewPager 2, FragmentPagerAdapter deprecated

En este tutorial explicamos como crear un TabLayout en Android Studio, también como cambiar de pestaña deslizando el dedo (ViewPager), algunos comandos del ViewPager están obsoletos (FragmentPagerAdapter deprecated) por lo que usaremos ViewPager2 con sus adaptadores.

Primero una breve explicación de los elementos de este tutorial.

¿Cuál es la función del TabLayout?

El TabLayout nos ayudará a tener múltiples pestañas o tabs, cada una contiene su propia interfaz de usuario y código.

Podemos cambiar de vista en la misma actividad, se usa un fragmento en cada pestaña.

TabLayout android Studio

¿Cuál es la función del ViewPager?

El ViewPeger nos da la opción de deslizar el dedo de manera horizontal en la pantalla y poder cambiar de pestaña o vista. Se conoce como vistas deslizantes.

ViewPager (FragmentPagerAdapter deprecated) es obsoleto, usamos ViewPager2.

Android se actualiza constantemente, por lo que algunos comandos o librerías se hacen obsoletos. Este es el caso de FragmentPagerAdapter, un elemento del ViewPager.

La solución es utilizar el ViewPager2 el cual contiene el elemento FragmentStateAdapter que se podría decir es el reemplazo del comando anterior.

Como resumen usaremos lo siguiente:

  • ViewPager2 en lugar de ViewPager..
  • FragmentStateAdapter en lugar de FragmentPagerAdapter.
  • La función setupWithViewPager(viewPager) ya no se usará. No hay una función directa que la reemplace, lo más cercano es la función TabLayoutMediator().

Creando un Tab Layout en Android Studio.

Ahora si vamos a hacer un TabLayout con las siguientes características:

  • 3 pestañas, cada una con un Fragmento.
  • Cambio entre pestañas deslizando el dedo de manera horizontal o presionando al título de la pestaña.

1.- Configurando la UI.

El diseño de la Interfaz de Usuario (UI) es muy simple, podemos agregar el Tablayout como cualquier otro elemento. Simplemente lo arrastramos a la vista o bien podemos escribir el código.

Al insertarlo aparece con 3 pestañas por default, en nuestro caso los títulos son algunos días de la semana.

Lo ponemos en la parte superior de la App, utilizamos ConstraintLayout para acomodarlo.

Y este es el código que se genera con las 3 pestañas.

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="1dp"
    android:layout_marginEnd="1dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tuesday" />

    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Monday" />

    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Wednesday" />
</com.google.android.material.tabs.TabLayout>

Debajo del TabLayout agregaremos un ViewPager2. Podemos arrastrarlo como cualquier otro elemento o bien escribir el código.

ViewPager2

Lo acomodaremos debajo del tablayout.

Este es el código de toda la UI:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tuesday" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Monday" />

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Wednesday" />
    </com.google.android.material.tabs.TabLayout>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        android:layout_width="409dp"
        android:layout_height="0dp"
        android:layout_marginBottom="16dp"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintBottom_toTopOf="@+id/btnMain"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tablayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

2.- Creando los fragmentos.

El siguiente paso es crear los fragmentos, en este caso son 3.

Para crear un fragmento damos clic derecho a la carpeta App, luego vamos a new/fragment y elegimos un Fragment(Blank).

Android Fragmento

Nos pedirá el nombre del fragmento, le damos el nombre que queramos, crearemos 3 fragmentos nuevos con los siguientes nombres:

  • FrHome
  • Fragmento2
  • Fragmento3

Cada fragmento tiene un código en Java o Kotlin y su interfaz en XML.

El código dentro de cada fragmento y la UI dependen de tu proyecto, por lo que aquí haremos algo muy sencillo:

  • En el TextView que tiene por default cada Fragmento, escribiremos el nombre del Fragmento para identificar si las pestañas del TabLayout están funcionando correctamente.
  • Generalmente se recomienda eliminar el código que aparece en el fragmento y dejar únicamente el onCreateView. Pero ya dependerá de tu proyecto.

3.- Adaptador para el ViewPager.

Necesitaremos un adaptador para poder incluir el ViewPager. Para esto creamos una nueva clase en Java y la llamaremos VPAdapter.

Para crear la clase damos clic derecho a la carpeta app, seleccionamos New/Java Class. Nos pedirá el nombre de la Clase, escribimos “VPAdapter

Extendemos la clase con FragmentStateAdapter.

Dentro de la clase lo primero que haremos es extender la clase con FragmentStateAdapter,  recuerda que FragmentPagerAdapter está obsoleto, además que estamos usando un ViewPager2.

public class VPAdapter extends fragmentStateAdapter{        .....          }

Implementamos métodos.

Nos aparecerá un error, Android nos sugiere implementar dos métodos.

FragmentStateAdapter

Implementamos los dos métodos sugeridos createFragment y getConut.

Agregamos un constructor.

Luego sigue apareciendo un error, ahora nos pide que agreguemos un constructor.

View Pager

Agregamos el constructor, nos aparecerán 3 opciones de constructor. Seleccionamos la primera, donde la variable de entrada es una Actividad. Asi queda el constructor:

public VPAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
}

Configurando detalles finales del adaptador.

Luego creamos una Lista con los títulos de los fragmentos, es importante que estén todos ya que lo usaremos para contar el número de pestañas. Estos títulos no se mostrarán, solo es una referencia para contar los fragmentos o pestañas.

Podemos usar simplemente el numero de fragmentos u otra variable proveniente de la actividad.

private String[] titulos = {"Titulo 1","Titulo 2", "Titulo 3"};

Creamos una variable

Después configuramos el return del método getItemCount, como sigue:

return titulos.length;

Podríamos escribir también el número de Fragmentos a usar.

Cambiando de Fragmento.

Por último configuramos el método createFragment()

Con la posición indicaremos que fragmento de debe abrir. Usaremos la función Switch para indicar que fragmento abrir de acuerdo a la posición seleccionada. Por default abriremos el FrHome.

@NonNull
@Override
public Fragment createFragment(int position) {
    switch (position){
        case 0:
            return new FrHome();
        case 1:
            return new Fragmento2();
        case 2:
            return new Fragmento3();
    }
    return new FrHome();
}

Este es el código completo del VPAdapter.java.

public class VPAdapter extends FragmentStateAdapter {

    private String[] titulos = {"Titulo 1","Titulo 2", "Titulo 3"};

    public VPAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position){
            case 0:
                return new FrHome();
            case 1:
                return new Fragmento2();
            case 2:
                return new Fragmento3();
        }
        return new FrHome();
    }

    @Override
    public int getItemCount() {
        return titulos.length;
    }
}

 

4.- Configurando la Actividad principal.

En la actividad principal primero debemos relacionar los elementos en XML con variables en el código.

Así que creamos dos variables una tipo TabLayout y otra tipo ViewPager. Para relacionarlas con los mismos elementos en la UI.

Además creamos una variable con los títulos que tendrá cada pestaña del TabLayout. Estos son los títulos que se mostraran en las pestañas.

private TabLayout tabLayout;
private ViewPager2 viewPager;
private String[] titulos = {"Home","F1","F2"};
private Context cont = this;

Dentro del método onCreate.

Aquí vamos a inicializar tanto el Tab Layout como el ViewPager, y unirlos para que trabajen juntos.

Primero relacionamos las variables creadas anteriormente con los elementos de la UI mediante su ID.

tabLayout = findViewById(R.id.tablayout);
viewPager = findViewById(R.id.viewpager);

Luego ocultamos la Action Bar si nuestro Proyecto lo require, para esto usamos el siguiente comando:

getSupportActionBar().hide();

Casi para terminar indicamos que el ViewPager2 usará el adaptador que creamos y llamamos  VPAdapter.

VPAdapter vpAdapter = new VPAdapter(this);
viewPager.setAdapter(vpAdapter);

Nota Importante: Si el constructor del VPAdapter no tiene como entrada una Actividad, puedes tener un error. Si esto ocurre te sugerimos borrar el constructor del VPAdapter e implementarlo de nuevo pero ahora que la variable sea una Actividad.

Por ultimo indicamos que trabajaran juntos el TabLayout y el ViewPager2. Además señalamos el título de cada una de las pestañas con el siguiente comando:

new TabLayoutMediator(tabLayout, viewPager, ((tab, position) -> tab.setText(titulos[position]))).attach();

Con esto ya debería funcionar el tabLayout cambiando de pestaña al deslizar el dedo de manera horizontal o bien presionando las pestañas.

Tab Layout Android

Este es el código de la Actividad Principal.

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager2 viewPager;
    private String[] titulos = {"Home","F1","F2"};
    private Context cont = this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = findViewById(R.id.tablayout);
        viewPager = findViewById(R.id.viewpager);

        getSupportActionBar().hide();

        VPAdapter vpAdapter = new VPAdapter(this);
        viewPager.setAdapter(vpAdapter);
        new TabLayoutMediator(tabLayout, viewPager, ((tab, position) -> tab.setText(titulos[position]))).attach();
    }
}

Para más tutoriales de Android ve a este enlace.

Algunos temas que te pueden interesar:

Shared Preferences Android Studio (Editar, Leer, Eliminar, datos).

 

Android seekbar