Crear Swipe Views En Android Con Tabs En La Action Bar

¿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.

El conocimiento de este artículo ha quedado atrás, revisa la nueva forma de crear pestañas con el TabLayout.

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

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

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 unas 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 ítems 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 título del ítem 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 índices 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 ítem 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 último 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 título de cada una con respecto al título 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));
    }
}

Hasta 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 más 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 ítems 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 ítem 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.

  • Jose Luis

    Hola!! Agradecerte por el curso, me a servido mucho, quisiera hacer una consulta, si quisiera cambiar el color de la “app” por decirlo así, en vez de rojo ponerla azul, digamos, donde debería de cambiarlo? Gracias, saludos.

    • Hola Jose. Me alegra que te sirva. Este tema ha variado mucho desde la aparición del Material Design. Usa este artículo nuevo para añadir pestañas:

      http://www.hermosaprogramacion.com/2015/06/tablayout-como-anadir-pestanas-en-android/

      El color de la app ahora se realiza con el estilo a través de los atributos primaryColor, accentColor, primaryDarkColor. En ese enlace se muestra como cambiarlos.

      Saludos compañero!

      • Jose Luis

        En serio te agradezco demasiado, veré qué tal el link & como poner los aportes que me indica. Sigue así compañero. 👌

        • Dale Jose, gracias

          • Jose Luis

            hola de nuevo James, quise probar la el codigo de la app, sin embargo, me dice que una clase: android.support.v4.view.viewpaper no esta, como podria importarla, o que debo hacer?

          • Hola Jose, ve a File y luego project structure. Luego selecciona la pestaña app. Luego clickea dependencies y presiona el botón “+” para añadir una nueva librería.

            Digita en la barra de búsqueda la palabra viewpager para ver si aparece como sugerencia.

            Aunque no se porque que te pide ese elemento como algo adicional si ya debe existir por defecto en el framework. Puedes poner un pantallazo del Android Studio?

  • victor

    Hola James! ¿Cómo estás? Me puse a leer el tutorial, y llevo al final y veo que comentas que ha quedado obsoleto el uso de pestañas, por lo tanto estás queriendo decir que no debemos desarrollar este sistema(Tabs/Pestañas) en una nueva app? o te refieres a este modo de desarrollarlo? Es decir que lo podemos hacer usando SlidingTabLayout? Me gusta mucho el uso de tabs y encima con swipes, da mucha fluidez, y si luego se le añaden efectos de transición más todavía y con el uso de Title Strip.

    Quería conocer tu opinión y aclarar tus conclusiones. Un saludo genio!

    Muchas gracias por todo!

  • Erik

    Hola. Excelente curso, es mucho más profundo y explicado que la gran mayoría que se encuentran.

    Tengo un problema en mi ViewPager. Lo estoy alimentando con un listado de unos 100 datos (frases), puse un botón de “share” para compartir por correo, facebook, whatsapp, etc, un único TextView que tengo en la vista del Fragment con el fin de compartir la frase activa. Es decir, me muevo de un lado a otro sobre las 100 frases y quiero que el usuario pueda compartir la que le guste. No lo he logrado, puedo hacer que comparta el texto dentro del TextView, pero pone el listado de las 100 frases, o si lo hago desde otro lado, me muestra la frase anterior, la actual y la siguiente. Lo que deseo es extraer únicamente la frase de la vista actual.

    Te agradezco mucho si me puedes ayudar.

    Saludos,

    Erik

  • Facundo Aramayo

    Hola.

    Antes que nada agradecer por el tutorial. Pero tengo una duda: Quiero que cada pestaña tenga diferentes tipos de contenidos, por ejemplo, en la primera un reproductor de música, en la segunda un visor de Twitter, en la tercera un campo de texto y botones con diferentes funciones. ¿Me dan una ayuda? ¿Cómo podría hacerlo?

    • SerGio Briceño Cupul

      Solo es necesario agragar un case dentro del Adaptador en getItem. Por lo que quedaria de la siguiente manera.

      public class TabsPagerAdapter extends FragmentPagerAdapter {

      public TabsPagerAdapter(FragmentManager fm) {
      super(fm);
      }

      @Override
      public Fragment getItem(int index) {

      switch (index) {
      case 0:
      return new Fragment1();
      case 1:

      return new Fragment2();
      case 2:

      return new Fragment3();
      }

      return null;
      }

      @Override
      public int getCount() {

      return 3;
      }

      }

  • AbelardoLG

    Hola a todos/as:

    Quisiera saber cómo cambiar/eliminar el icono que acompaña al nombre “Foodsty” colocado en la parte superior izquierda de la aplicación.

    Tras mirar el código, no sé en dónde está para hacerlo.

    Muchas gracias por la información.

    Saludos cordiales.

  • No consigo como crear un sistema de pestañas pero que con el botón atrás vaya volviendo por las pestañas visitadas y tambien como realizar un step step, que si no hay los campos validados no deje hacer swipe a la siguiente pestaña

  • Miquel Àngel Bardají

    Hola, el código no esta disponible sabes como lo podría conseguir por favor?
    Si he compartido en las redes sociales, pero luego me sale un 404.

    además creandolo yo, siempre me falla por NullPointer excepction cuando ejecuto

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    supongo que por que en la instrucción anterior

    final ActionBar actionBar = getActionBar(); no se inicializa bien la variable.

    Sabes que le puede fallar o que hace esta acción en concreto? Por que no se si es que en mi proyecto le debo poner una action bar o no se… soy novato la verdad

  • Cristian

    hola que tal, saben donde puedo ver el codigo completo?

  • Kryancelt Belmont

    muy bien explicaado pero como puedo que controlar cuando se presione en el contenido de una pestaña ue me envie a otra vista?
    hay un metodo a considerar para eso?

  • Oscar Salcedo

    Una pregunta y si quisiera poner las pestañas en la parte inferior de la pantalla como tendría que hacer, gracias por tu respuesta!!

  • Juan Diego Hernandez

    Buenas tardes amigo.
    Primero agradecerte por el tutorial, segundo, hay manera de que hagas un videotutorial en el que expliques este mismo ejemplo, pero usando Toolbar?.
    Por ultimo, el codigo no se deja descargar, parece que se borro de tu Dropbox.

    • Hola Juan.

      Si he pensado en algunos tutoriales, pero me gustaría primero escribir sobre varios temas antes.

      El código está disponible. Acabo de comprobar el enlace y todo va bien. ¿Has intentado probar compartir con otra red social?

  • Luis Fernando Pinzon

    Despues de unos cuantos intentos he logrado conseguirlo, pero tengo una duda y si quiero meter un listView dentro de cada tab? seria posible esto

    • Claro compañero, puedes fragmentos con listas incluidas en sus layouts.

  • Fidel

    Hola, primero agradecerte por el tutorial me ha servido de mucho, segundo quisiera hacerte una pregunta acerca de un error qeu me sale cuando intento llamar diferente fragmentos en getItem() de la siguiente manera.

    public Fragment getItem(int position) {
    Fragment fragment=null;
    switch (position){
    case TAB_MAPA:
    fragment = Mapa.newInstance(” “,” “);
    break;
    case TAB_AMIGOS:
    fragment = Amigos.newInstance(” “,” “);
    break;
    }
    return fragment;
    // return MyFragment.getInstance(position);
    }

    cuando intento desplazarme entre los tabs me generar un erro de puntero null asociado a la clase FragmentStatePagerAdapter, me gustaría saber si sabes porque puede ser este error o si estoy haciendo algo mal en el getItem

    este el código del fragmento

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_amigos, container, false);
    }
    public static Amigos newInstance(String param, String param2){

    Amigos myFragment=new Amigos();
    Bundle args=new Bundle();
    myFragment.setArguments(args);
    return myFragment;
    }

    Mucha gracias.

    • Fidel

      Este es el error que me sale :
      java.lang.NullPointerException
      at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:116)
      at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:836)
      at android.support.v4.view.ViewPager.populate(ViewPager.java:1052)
      at android.support.v4.view.ViewPager.populate(ViewPager.java:918)
      at android.support.v4.view.ViewPager$3.run(ViewPager.java:248)
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
      at android.view.Choreographer.doCallbacks(Choreographer.java:579)
      at android.view.Choreographer.doFrame(Choreographer.java:547)
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
      at android.os.Handler.handleCallback(Handler.java:800)
      at android.os.Handler.dispatchMessage(Handler.java:100)
      at android.os.Looper.loop(Looper.java:194)
      at android.app.ActivityThread.main(ActivityThread.java:5405)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:525)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:838)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
      at dalvik.system.NativeStart.main(Native Method)

      gracias

    • James Revelo

      Hola amigo.

      Tal vez tu switch en getItem() está recibiendo una posición distinta a tus opciones. ¿Ya comprobaste que opción está llegando?, loguea con Log.d() y revisa.

  • Oscar

    Como hiciste los iconos de las categorías de los productos?

    Gracias por tu curso!

    • James Revelo

      Hola Oscar.

      Los íconos puedes crearlos a partir de una imagen PNG con dos herramientas:
      1. Ve a esta herramienta online y selecciona una imagen PNG y descarga los iconos.
      2. En Android Studio existe un asistente para crear nuevos iconos. Se llama Image Asset. Puedes encontrarlo cuando presionas click derecho en tu carpeta drawable y seleccionas la opción “New”. Cuando inicies este asistente solo seleccionas la imagen PNG e inmediatamente se añadirá a tu proyecto.

      Las imágenes las conseguí con transaparencia cuando las descargué en iconfinder.com.

      Espero te sea de utilidad esta respuesta. Saludos!

  • Jose Alberto

    Hola de nuevo!!

    Genial este articulo!! Lo estoy usando para hacer una pequeña práctica pero estoy teniendo un problema con una cosilla. En el fragment tengo un textview en cual quiero que aparezcan una serie de títulos que se vayan cambiando según pasas las páginas. Estos títulos los tengo definidos en el archivo strings.xml . Cualquier ayuda será bien recibida.
    Gracias por adelantado y un saludo!!

    • James Revelo

      Hola Jose, no se si te refieras a leer los valores del strings.xml.

      Si es eso, entonces solo obtén el recurso de la siguiente forma:

      String tuString = getResources().getString(R.string.tu_string);

      Saludos!