miércoles, 18 de mayo de 2022

52 - Componente ViewPager

La componente ViewPager es muy utilizada en aplicaciones Android, la misma nos permite mostrar distintas pantallas desplazando la página actual con el dedo a izquierda o derecha como si fuera un libro que pasamos sus hojas.



Visualmente podemos ver que la clase ViewPager implementa la animación de desplazamiento al arrastrar el dedo:

ViewPager

Esta componente visual nos facilita el desarrollo de esta funcionalidad de múltiples páginas.

Para conocer su funcionamiento implementaremos una aplicación que tenga tres páginas administradas mediante un ViewPager.

La primer página mostrará un ListView con un conjunto de sitios web de buscadores, la segunda página mostrará otro ListView con sitios de periódicos y la tercer página mostrará el nombre del programador y fecha de creación en dos TextView.

En la parte superior dispondremos tres botones para ir directamente a una de dichas páginas sin tener que hacer el gesto de desplazar con el dedo.

Problema:

Lo primero que hacemos es crear un proyecto con el Android Studio llamado "Proyecto057".

Debemos disponer tres botones y un objeto de tipo ViewPager en el archivo 'activity_main.xml', los tres botones fácilmente los arrastramos de la paleta de componentes pero veremos que no se encuentra la clase 'ViewPager'. Tenemos dos posibilidades, una es escribir directamente en XML o la otra es seleccionar 'CustomView' en la paleta de componentes y buscar la clase 'ViewPager':

ViewPager

En el diálogo que aparece seleccionamos la clase 'ViewPager':

ViewPager

y luego de seleccionarla la arrastramos dentro de la imagen del celular:

ViewPager

Con esto ya tenemos agregada la componente 'ViewPager' en el archivo XML.

El archivo "activity_main.xml" final queda:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.tutorialesprogramacionya.proyecto057.MainActivity">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Buscadores"
android:id="@+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="irPagina1" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Periódicos"
android:id="@+id/button2"
android:layout_alignTop="@+id/button"
android:layout_toRightOf="@+id/button"
android:layout_toEndOf="@+id/button"
android:onClick="irPagina2" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Acerca de"
android:id="@+id/button3"
android:layout_alignBottom="@+id/button2"
android:layout_toRightOf="@+id/button2"
android:layout_toEndOf="@+id/button2"
android:onClick="irPagina3" />

<android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/view"
android:layout_below="@+id/button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>

Como vemos a cada uno de los botones definimos su propiedad onClick para implementar posteriormente su funcionalidad.

La clase ViewPager se ha introducido en las versiones más modernas de Android y para que pueda ser utilizada por versiones anteriores se han creado librerías de compatibilidad, en el caso del la clase 'ViewPager' se encuentra en android.support.v4, de esto surge la diferencia cuando la declaramos en el archivo XML:

    <android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/view"
android:layout_below="@+id/button"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />

El segundo paso será crear los tres archivos XML con las interfaces visuales de cada página que mostrará el 'ViewPager'. Presionamos el botón derecho del mouse sobre la carpeta Layout del Android Studio y seleccionamos New -> XML -> Layout XML File:

ViewPager nuevo XML archivo

En este diálogo debemos definir el nombre del archivo (pagina1) y el tipo de Layout raíz (dejamos por defecto el LinearLayout que se propone):

ViewPager nuevo XML archivo

Disponemos el ListView que mostrará la pagina1.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView"
android:layout_weight="1" />
</LinearLayout>

De forma similar creamos el archivo pagina2.xml y disponemos también un 'ListView':

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView2"
android:layout_weight="1" />
</LinearLayout>

Creamos el tercer archivo XML 'pagina3.xml' pero insertamos en el mismo dos TextView para que muestren el nombre del programador y fecha de creación de este programa:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Pablo Martinez"
android:id="@+id/textView2" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="2016"
android:id="@+id/textView" />
</LinearLayout>

Ya tenemos creados los cuatro archivos XML y sus componentes visuales:

ViewPager

El tercer paso vamos a crear el código java para administrar el ViewPager, para esto codificamos en el archivo 'MainActivity.java' lo siguiente:

package com.tutorialesprogramacionya.proyecto057;

import android.content.Intent;
import android.net.Uri;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

private ViewPager view1;
private LinearLayout pagina1;
private LinearLayout pagina2;
private LinearLayout pagina3;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view1=(ViewPager)findViewById(R.id.view);
view1.setAdapter(new AdminPageAdapter());
}

class AdminPageAdapter extends PagerAdapter
{

@Override
public int getCount()
{
return 3;
}

@Override
public Object instantiateItem(ViewGroup collection, int position)
{
View paginaactual = null;
switch (position)
{
case 0:
if (pagina1 == null)
{
pagina1 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina1, null);
cargarBuscadores();
}
paginaactual = pagina1;
break;
case 1:
if (pagina2 == null)
{
pagina2 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina2, null);
cargarPeriodicos();
}
paginaactual = pagina2;
break;
case 2:
if (pagina3 == null)
{
pagina3 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina3, null);
}
paginaactual = pagina3;
break;
}
ViewPager vp=(ViewPager) collection;
vp.addView(paginaactual, 0);
return paginaactual;
}

@Override
public boolean isViewFromObject(View view, Object object)
{
return view == object;
}

@Override
public void destroyItem(View collection, int position, Object view)
{
((ViewPager) collection).removeView((View) view);
}
}



private void cargarBuscadores() {
final String []sitios={"google.com.ar","yahoo.com.ar","bing.com"};
ArrayAdapter<String> adaptador1=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,sitios);
ListView lv1=(ListView)pagina1.findViewById(R.id.listView);
lv1.setAdapter(adaptador1);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intento1=new Intent(Intent.ACTION_VIEW, Uri.parse("http://www."+sitios[position]));
startActivity(intento1);
}
});
}

private void cargarPeriodicos() {
final String []sitios={"lanacion.com.ar","clarin.com.ar","lavoz.com.ar"};
ArrayAdapter<String> adaptador1=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,sitios);
ListView lv1=(ListView)pagina2.findViewById(R.id.listView2);
lv1.setAdapter(adaptador1);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intento1=new Intent(Intent.ACTION_VIEW, Uri.parse("http://www."+sitios[position]));
startActivity(intento1);
}
});
}


public void irPagina1(View v) {
view1.setCurrentItem(0);
}

public void irPagina2(View v) {
view1.setCurrentItem(1);
}

public void irPagina3(View v) {
view1.setCurrentItem(2);
}
}

En el archivo MainActivity definimos el objeto de la clase ViewPager y tres variables que tendrán la referencia a cada página(el elemento raiz de cada página es un LinearLayout):

    private ViewPager view1;
private LinearLayout pagina1;
private LinearLayout pagina2;
private LinearLayout pagina3;

En el método onCreate obtenemos la referencia del ViewPager y llamamos al método setAdapter pasando como dato un objeto anónimo de la clase AdminPageAdapter que es una clase interna que debe heredar de la clase PageAdapter:

        view1=(ViewPager)findViewById(R.id.view);
view1.setAdapter(new AdminPageAdapter());

La clase AdminPageAdapter debe heredar como dijimos de la clase PageAdapter y debe sobreescribir una serie de métodos para implementar la funcionalidad del ViewPager para nuestro problema:

    class AdminPageAdapter extends PagerAdapter

El método getCount debe retornar la cantidad de páginas que tiene nuestro ViewPager (en nuestro ejemplo tiene tres páginas:

        @Override
public int getCount()
{
return 3;
}

También debemos sobreescribir el método instantiateItem donde según el valor que llega en el parámetro 'position' procedemos a cargar el archivo de la página XML a mostrar (esto es así ya que es una funcionalidad ya implementada por la clase PageAdapter):

        @Override
public Object instantiateItem(ViewGroup collection, int position)
{
View paginaactual = null;
switch (position)
{
case 0:
if (pagina1 == null)
{
pagina1 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina1, null);
cargarBuscadores();
}
paginaactual = pagina1;
break;
case 1:
if (pagina2 == null)
{
pagina2 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina2, null);
cargarPeriodicos();
}
paginaactual = pagina2;
break;
case 2:
if (pagina3 == null)
{
pagina3 = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.pagina3, null);
}
paginaactual = pagina3;
break;
}
ViewPager vp=(ViewPager) collection;
vp.addView(paginaactual, 0);
return paginaactual;
}

Debemos implementar los métodos isViewFromObject y destroyItem para el correcto funcionamiento de la clase PageAdapter:

        @Override
public boolean isViewFromObject(View view, Object object)
{
return view == object;
}

@Override
public void destroyItem(View collection, int position, Object view)
{
((ViewPager) collection).removeView((View) view);
}

Como vemos si ejecutamos la aplicación podemos desplazar cada página con los dedos de izquierda a derecha, pero también podemos cambiarnos de página presionando alguno de los tres botones dispuestos en la parte superior de la pantalla:

    public void irPagina1(View v) {
view1.setCurrentItem(0);
}

public void irPagina2(View v) {
view1.setCurrentItem(1);
}

public void irPagina3(View v) {
view1.setCurrentItem(2);
}

ViewPager

Este proyecto lo puede descargar en un zip desde este enlace: proyecto057.zip

No hay comentarios:

Publicar un comentario