Listado completo de tutoriales
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:
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.
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':
En el diálogo que aparece seleccionamos la clase 'ViewPager':
y luego de seleccionarla la arrastramos dentro de la imagen del celular:
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:
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):
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:
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); }
Este proyecto lo puede descargar en un zip desde este enlace: proyecto057.zip