Crear Swipe Views en Android con Tabs en la Action Bar

Añadir Tabs a la Action Bar para usar Swipe Views
¿Te has preguntado como implementar pestañas en la Action Bar de tu aplicación Android, pero aún no encuentras el tutorial indicado?, si la respuesta es afirmativa, entonces te aseguro que este artículo te será de gran ayuda. Quédate y podrás aclarar el uso de Tabs y la navegación horizontal en tus aplicaciones Android.

Además terminarás creando una aplicación con el siguiente aspecto:

(Link de descarga al final del tutorial)

Conocimientos que aprenderás:
CONTENIDO

Patrón de paginado horizontal en Android

Ejemplo de una Aplicación Android para un Restaurante

Usar un ViewPager con fragmentos
Añadir elementos a un ViewPager con un FragmentPagerAdapter

Definición del Fragmento para el Adaptador

Añadir tabs a la Action Bar

Coordinar los elementos del ViewPager con las Tabs

Bonus: Implementación de un Title Strip en Android

Consideraciones Finales

Patrón de paginado horizontal en Android

El API de Android provee a los programadores muchas formas de navegación para implementar en sus aplicaciones. Una de ellas es el Paginado Horizontal o también llamado Swipe Views Pattern. Con este diseño el usuario cambia entre secciones de la aplicación con un gesto de arrastre horizontal en su dispositivo móvil. Veamos un ejemplo:

Swipe Gesture en la aplicación Contactos de Android
Además de la elegancia visual que proyectan los Swipe Views, también permiten una accesibilidad intuitiva y cómoda por parte del usuario al contenido principal de tu aplicación, mejorando la experiencia de su estadía.

Ejemplo de una Aplicación Android para un Restaurante

Como se vio al principio de este articulo, se ha creado una aplicación con un secciones de pedidos en un Restaurante llamada "Foodsty". Esta nos servirá de respaldo para aclarar el uso de Tabs en la Action Bar (Lee también Tutorial de la Action Bar en Android).

Lógicamente Foodsty consta de una actividad principal llamada Main junto a un archivo de diseño activity_main.xml. Adicionalmente se ha creado un archivo de diseño para los fragmentos que se usarán como items en el ViewPager, cuyo nombre es fragment_content.xml.

El objetivo de esta aplicación es mostrar una lista de cada uno de los productos disponibles por la tienda hipotética Foodsty, dependiendo de las tres categorías disponibles: "Platillos", "Postres" y "Bebidas".

El usuario podrá cambiar entres pestañas pulsando cada pestaña en la action bar (gesto tap) o arrastrando horizontalmente el contenido de las categorías (gesto swipe). Con estas características claras comencemos a crear nuestra aplicación Foodsty.

Usar un ViewPager con Fragmentos

Un ViewPager es un widget que permite mostrar contenido en páginas o secciones individuales. Para intercambiar entre elementos se usa el gesto swipe de izquierda a derecha o viceversa. Al implementarlo es necesario crear un adaptador del tipo PagerAdapter, que infle cada página de forma individual. Este proceso es muy parecido a cuando usábamos listas (Lee también Listas y Adaptadores en Android).

Dicho elemento pertenece a la Librería de soporte v4, así que no olvides incluir la dependencia en Gradle.

Debido a que la actividad principal de Foodsty está basada en un ViewPager, se debe implementar un nodo raíz del tipo <ViewPager>.

Veamos:

// Archivo activity_main.xml
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Añadir elementos a un ViewPager con un FragmentPagerAdapter

Lo siguiente es poblar nuestro ViewPager a través de un adaptador del tipo FragmentPagerAdapter. Esta subclase es una implementación especial para utilizar fragmentos en las páginas. ¿Por qué fragmentos?, porque así podrás tener el control del ciclo de vida del contenido, lo que te permite mayor flexibilidad en las operaciones que desees realizar.

Usa FragmentPagerAdapter, si con antelación conoces la cantidad de fragmentos que tendrá tu ViewPager. De lo contrario usa el adaptador FragmentStatePagerAdapter para indicar que la cantidad será variable. Esta clase te ayudará a liberar memoria de aquellos fragmentos que no tienen el foco.

Crear nuestro propio adaptador de fragmentos es muy simple. Solo debes tener claro los siguientes elementos básicos a sobrescribir:

Constructor: Es necesario crear un constructor que reciba el FragmentManager(Lee también Fragmentos en una aplicación Android) asociado al contexto donde se ejecuta el ViewPager.

getCount(): Sobrescribe este método para que retorne en la cantidad de elementos que tendrá tu pager.

getPageTitle(): Este método permite obtener el título de cada pestaña. Condiciona con un switch la posición de cada fragmento para asignar el nombre correcto.

getItem(): Este es el método que fabrica cada uno de los fragmentos de acuerdo a las características que hayas declarado.Aclaradas estas especificaciones podemos ver la definición del adaptador FoodPagerAdapter:

Adaptador de fragmentos para el ViewPager

public static class FoodPagerAdapter extends FragmentPagerAdapter {
public FoodPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0: return "PLATILLOS";
case 1: return "POSTRES";
case 2: return "BEBIDAS";
default: return "";
}
}
@Override
public Fragment getItem(int i) {
// Crear un FoodFragment con el nombre como argumento
Fragment fragment = new FoodFragment();
Bundle args = new Bundle();
args.putString(FoodFragment.ARG_SECTION_NAME, getPageTitle(i).toString());
args.putInt(FoodFragment.ARG_SECTION_IMAGE, i);
fragment.setArguments(args);
return fragment;
}
}

Si prestas atención, FoodPagerAdapter es una clase estática anidada debido a que solo la usaremos en este contexto. Otra propiedad a destacar es que su método getItem() genera fragmentos del tipo FoodFragment, clase que veremos enseguida.

Adicionalmente envía como argumento el titulo del item y el id de la imagen de presentación que se usará. Por lo que se usan las constantes ARG_SECTION_NAME y ARG_SECTION_IMAGE.

Definición del Fragmento para el Adaptador

El contenido de cada página es un simple TextView informativo que muestra la pestaña actual y una imagen alusiva al contenido. El texto mostrado representa el tipo de elementos que alberga el fragmento, algo como "Lista de <TipoElementos>". Así que cada vez que el usuario cambie las pestañas, la cadena se irá actualizando en tiempo real para reflejar el estado.

Esclarecida esta idea, creamos un layout sencillo para ubicar estos dos elementos:

// Archivo fragment_content.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="240dp"
android:id="@+id/imageView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scaleType="fitXY" />
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="24sp"
android:padding="32dp"
android:layout_below="@+id/imageView"
android:textColor="#c23"
android:textStyle="bold" />
</RelativeLayout>

Ahora se declara la clase FoodFragment para representar el contenido:

Fragmento que usaremos para cada pestaña

public static class FoodFragment extends Fragment {
public static final String ARG_SECTION_NAME = "section_name";
public static final String ARG_SECTION_IMAGE = "section_image";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_content, container, false);
Bundle args = getArguments();
// Setear la imagen al fragmento
ImageView image = (ImageView)rootView.
findViewById(R.id.imageView);
image.setImageResource(imgIds[args.getInt(ARG_SECTION_IMAGE)]);
// Setear el texto
((TextView) rootView.findViewById(android.R.id.text1)).setText(
getString(R.string.section_title)+" "+args.getString(ARG_SECTION_NAME));
return rootView;
}
}

FoodFragment también es una clase estática interna. Aunque para este ejemplo solo se declaró esta clase, ya que se usará la misma estructura en las 3 pestañas, no significa que siempre debas proceder de esta forma. Crea diferentes clases para cada fragmento si estos son completamente distintos y maneja la situación con un switch.

Puedes crear un array global de tipo Fragment dentro del adaptador e inicializarlo en su constructor con los fragmentos de distinta clase. Con esa definición estas habilitado para usar los indices del array en el método getItem() en vez de preocuparte por sus tipos.

Añadir Tabs a la Action Bar

Lo primero que se debe hacer para crear pestañas dentro de la Action Bar es activar su modo de navegación por tabs. Para ello, obtén una instancia de la Action Bar y luego usa el método setNavigationMode(). Este recibe como parámetro la constante del modo de navegación, que en este caso será NAVIGATION_MODE_TABS:

// Obtener instancia de la Action Bar
final ActionBar actionBar = getActionBar();
// Activar el modo de navegación con tabs en la Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

La lectura de eventos de las pestañas se realiza con la interfaz TabListener de la clase ActionBar. A cada pestaña se le debe asignar la escucha para que pueda responder a las instrucciones establecidas. Así que relacionaremos nuestra actividad principal con TabListener y sobrescribiremos los métodos de esta escucha:

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
...
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// Nada por hacer
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// Coordinar la pestaña seleccionada con el item del viewpager
viewpager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// Nada por hacer
}
}

El método onTabSelected() se ejecuta cuando el usuario selecciona una pestaña, justo en ese momento actualizamos el contenido del ViewPager con setCurrentItem(), que recibe la posición del item a establecer en el foco. Esta posición se obtiene con getPosition() de la tab actualmente procesada.

onTabUnselected() se ejecuta cuando la pestaña sale del estado de selección y onTabReselected() es iniciado cuando el usuario selecciona una pestaña que actualmente se encuentra seleccionada.

Por ultimo se crean 3 tabs con el método newTab() y se añaden con addTab():

// Añadir 3 pestañas y asignarles un título y escucha
for (int i = 0; i < adapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(adapter.getPageTitle(i))
.setTabListener(this));
}

Usa setText() para añadir el titulo de cada una con respecto al titulo del elemento correspondiente del adaptador y relaciona la escucha implementada con setTabListener().

Coordinar los elementos del ViewPager con las Tabs

Hasta ahora el usuario puede hacer tap en las pestañas y ver el contenido, pero aún no puede usar el gesto swipe. Por eso implementaremos la interfaz OnPageChangeListener sobre nuestro pager. Con ella podemos sincronizar el cambio de pestañas cuando se cambie las páginas, es decir, el efecto contrario a cuando implementamos TabListener.

viewpager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// Coordinar el item del pager con la pestaña
actionBar.setSelectedNavigationItem(position);
}
});

Usa SimpleOnPageChangeListener si deseas implementar solo los métodos necesarios de OnPageChangeListener.

Como ves, se usa el método setOnPageChangeListener() para añadir la escucha. El método onPageSelected() se ejecuta cuando la página es seleccionada, por lo que se ordena en ese instante que la action bar cambie la pestaña a la posición determinada por el parámetro de entrada position.

Finalmente junta todas las declaraciones y compone el método onCreate() de la actividad principal:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtener instancia de la Action Bar
final ActionBar actionBar = getActionBar();
// Activar el modo de navegación con tabs en la Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Deshabilitar el caret Up del icono de la aplicación
actionBar.setHomeButtonEnabled(false);
// Crear adaptador de fragmentos
adapter = new FoodPagerAdapter(getSupportFragmentManager());
// Obtener el ViewPager y setear el adaptador y la escucha
viewpager = (ViewPager) findViewById(R.id.pager);
viewpager.setAdapter(adapter);
viewpager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// Coordinar el item del pager con la pestaña
actionBar.setSelectedNavigationItem(position);
}
});
// Añadir 3 pestañas y asignarles un título y escucha
for (int i = 0; i < adapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(adapter.getPageTitle(i))
.setTabListener(this));
}
}

Puedes descargar el código de todo el proyecto desde el siguiente enlace:

Descargar CódigoHasta este momento la aplicación se vería de esta forma:

Aplicación Android de un Restaurante con solo texto en las Tabs
Pero si tu eres mas fino y deseas usar iconos en cada pestaña, entonces buscas los drawables correspondientes y empleas el método setIcon() para asignarlos.

//Las referencias de tus iconos
int idIcons[] = {R.drawable.icon1, R.drawable.icon2, R.drawable.icon3};
// Añadir 3 pestañas y asignarles un título y escucha
for (int i = 0; i < adapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setIcon(idIcons[i])
// Habilita el titulo si lo prefieres
// .setText(adapter.getPageTitle(i))
.setTabListener(this));
}

Con estos cambios la aplicación mutaría de esta forma:

Aplicación Android de un Restaurante con iconos en las Tabs
Android Studio proporciona un método automático para generar una actividad con pestañas más el uso de Swipe Views con un ViewPager. Solo debes ubicarte en tu paquete java y dar click derecho, luego eliges New > Activity > Tabbed Activity.

Tabbed Activity en Android Studio
Bonus: Implementación de un Title Strip en Android

Los Title Strips crea pestañas dinámicas en un ViewPager. Se asemejan mucho a las pestañas de la action bar, solo que estos no tienen interacción con el usuario. Además un Title Strip muestra en tiempo real los items anteriores, el actual y los siguientes, a diferencia de las tabs que se mantienen fijas.

Su implementación es muy sencilla, solo anidas un elemento del tipo <android.support.v4.view.PagerTitleStrip> dentro del elemento <ViewPager>. Cada pestaña toma el nombre de la página correspondiente con el método getPageTitle(), así que no debes preocuparte por implementarlo programáticamente.

Si deseas reemplazar las tabs por un PagerTitleStrip entonces elimina todas las implementaciones de la action bar y agrega el elemento al archivo de diseño:

// Archivo activity_main.xml con PagerTitleStrip
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTitleStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#c23"
android:textColor="#fff"
android:paddingTop="4dp"
android:paddingBottom="4dp" />
</android.support.v4.view.ViewPager>

Este diseño produciría el siguiente resultado:

Como alternativa, puedes ajustar el atributo layout_gravity para que el Title Strip gravite en la parte inferior "bottom".

Un dato más. También es posible usar un Tab Strip con un indicador interactivo y visual, cuyo nombre es PagerTabStrip. Este View utiliza una pequeña barra lateral que se desliza de un item a otro para representar la interacción con las páginas. Si quieres implementarlo solo cambia por el elemento <PagerTabStrip> en tu archivo de diseño:

Consideraciones Finales

En la nueva API 21 los modos de navegación de la action bar han quedado obsoletos, por lo cual el uso de pestañas en la Action Bar no son recomendables en el uso de aplicaciones para Android Lollipop, pero aún podemos usarlas en versiones anteriores. Recuerda que la propagación de un nuevo sistema operativo requiere cierto tiempo para dominar considerablemente una cuota de mercado. No obstante, el centro de desarrollo de Android recomienda el uso del componente SlidingTabLayout para la creación de pestañas.

También es importante saber que en el API 21 se ha creado un nuevo widget llamado Toolbar, el cual puede reemplazar la Action Bar. Este nuevo componente es muy flexible a la hora de modificar su aspecto y agregarle estilo (Hablaremos sobre él en futuros artículos).

Para la creación del estilo de Foodsty se usó la herramienta de código abierto Android Action Bar Style Generator de Jeff Gilfelt. Con ella puedes modificar el estilo de cada componente de la action bar, como el background, la transparencia, el tema padre, etc y producir todos los drawables necesarios para generar un tema global de la aplicación (Lee también Diseñar Temas y Estilos para tus Aplicaciones Android).Iconos cortesía de IconFinder. Imágenes cortesía de Freepik.

James Revelo Urrea - Desarrollador independiente http://www.hermosaprogramacion.com

Fuente: este post proviene de Hermosa Programación, donde puedes consultar el contenido original.
¿Vulnera este post tus derechos? Pincha aquí.
Creado:
¿Qué te ha parecido esta idea?

Esta idea proviene de:

Y estas son sus últimas ideas publicadas:

Recomendamos

Relacionado

informática desarrollo android

IMG.displayed{display:block;margin-left:auto;margin-right:auto} En este articulo estudiaremos las características y el uso de la Action Bar (Barra de acción) en el desarrollo Android. Veremos su anatomía, como crear un archivo de diseño para ella, como ejecutar las acciones una vez presionado sus opciones y otras características relevantes. Indice: Funciones del Action Bar Anatomía de la Action ...

informática desarrollo android

IMG.displayed{display:block;margin-left:auto;margin-right:auto} En este articulo estudiaremos las características y el uso de la Action Bar (Barra de acción) en el desarrollo Android. Veremos su anatomía, como crear un archivo de diseño para ella, como ejecutar las acciones una vez presionado sus opciones y otras características relevantes. Indice: Funciones del Action Bar Anatomía de la Action ...

informática desarrollo android

Este artículo te explicará el uso del Navigation Drawer en Android para crear una navegación a través de un Menú deslizante. Verás como implementar un Drawer Layout para el diseño. Aprenderás a manejar los eventos relacionados. Y también a complementar su funcionamiento con la action bar mediante un Action Bar Drawer Toggle. CONTENIDO ¿Cómo crear un menú deslizante con un Navigation Drawer? Ejem ...

informática desarrollo android

Este artículo te explicará el uso del Navigation Drawer en Android para crear una navegación a través de un Menú deslizante. Verás como implementar un Drawer Layout para el diseño. Aprenderás a manejar los eventos relacionados. Y también a complementar su funcionamiento con la action bar mediante un Action Bar Drawer Toggle. CONTENIDO ¿Cómo crear un menú deslizante con un Navigation Drawer? Ejem ...

informática android apps ...

En este artículo veremos que son Layouts y Views para el diseño de la interfaz de usuario (UI) de una aplicación Android. Crearemos una pequeña aplicación paso a paso para comprender como definir nuestros diseños, relacionarlos con el código Java y manejar eventos disparados por el usuario al interactuar con la interfaz. ¿Java o XML? Cuando vimos la estructura de un proyecto en Android, hablamos s ...

informática material design desarrollo android

¿Aún no sabes usar el RecyclerView en conjunto con CardViews?, ¿Quieres que tus aplicaciones proyecten las nuevas nociones del Material Design en su interfaz?, entonces este tutorial es para ti. Verás cómo crear paso a paso una lista contenedora de tarjetas estilizadas, donde se proyectaran los atributos de elevación y bordes redondeados  para hacer una interfaz novedosa. CONTENIDO Crear lista ...

informática android aplicaciones ...

En este artículo descubriremos el poder de los fragmentos en el desarrollo de aplicaciones Android. Entenderemos su concepto y propósito, el ciclo de vida que poseen, las ventajas que tiene usarlos y como crearlos en nuestros proyectos en Android Studio de forma declarativa y programática. ¿Qué es un fragmento? La necesidad de usar fragmentos nace con la versión 3.0 (API 11) de Android debido a lo ...

informática android aplicaciones ...

En este artículo descubriremos el poder de los fragmentos en el desarrollo de aplicaciones Android. Entenderemos su concepto y propósito, el ciclo de vida que poseen, las ventajas que tiene usarlos y como crearlos en nuestros proyectos en Android Studio de forma declarativa y programática. ¿Qué es un fragmento? La necesidad de usar fragmentos nace con la versión 3.0 (API 11) de Android debido a lo ...

informática desarrollo android

¿Andas buscando como parsear un archivo RSS con formato XML, para incluir contenidos de un sitio web en tu aplicación Android? ¿Necesitas ideas para crear una app lectora de Rss como Feedly, Flipboard o Flyne? Pues bien, en este tutorial verás cómo alimentar una lista de elementos con las noticias del sitio web forbes.com desde su feed con formato RSS a través de las tecnologías Volley y Simple Fr ...

informática desarrollo android

¿Quieres cargar más elementos en tu lista usando un indicador de actividad circular que muestran muchas otras aplicaciones Android? Entonces este tutorial es para ti, ya que te enseñará a usar el patrón de diseño "Swipe to Refresh", el cual refresca el contenido de una view con tan solo arrastrar verticalmente la interfaz. Para comprender este tema crearemos una pequeña aplicación llam ...