Cómo crear Swipe Views con tabs distintas en la Action Bar de forma fácil

Manuel Mato
Aug 9, 2017 · 5 min read

Remitiéndonos a la documentación de Android developer, las vistas panorámicas nos permiten desplazarnos con un gesto horizontal entre pantallas de una misma activity, como van a ser en nuestro ejemplo las pestañas.

En la activity principal al presionar el botón, nos llevará a la segunda activity en la que tendremos dos tabs de desplazamiento horizontal y con distinto contenido:

Para hacerlo de una forma sencilla, nos aprovecharemos del IDE Android Studio y crearemos:

Activity principal: contendrá el botón que nos llevará a la activity TabsActivity

TabsActivity: la clase que gestionará qué pestañas mostrar.

TabAFragment: es un fragment que contendrá un text view y se mostrará en la primera pestaña.

TabBFragment: es un fragment que contendrá un text view y se mostrará en la segunda pestaña.

No me voy a parar a explicar todos los métodos y funcionamiento, para eso ya hay bastante información en google ;)

Activity principal

En el layout principal activity_main ponemos un Button con el atributo text “Mostrar segunda activity” y hacemos un listener que lance un intent a ActivityTabs.class:

xml

<Button
android:id="@+id/boton_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mostrar segunda activity" />

.java

TextView botonSegundaActivity = (TextView) findViewById(R.id.boton_activity);botonSegundaActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, TabsActivity.class);
startActivity(i);
}
});

TabsActivity

Sobre el paquete donde se encuentra la clase principal, creamos una nueva Tabbed Activity: New -> Activity -> Tabbed Activity. En nuestro ejemplo, usaremos las pestañas en la Action Bar: Navigation Style -> Action Bar Tabs (with ViewPager).

Al hacerlo de esta manera se nos crea de forma automática un activity_tabs xml que contendrá los widgets que nos interesan: AppBarLayout, Toolbar, TabLayout y el ViewPager. En este ejemplo no necesitamos el FloatingActionButton.

xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.manuel.swipetabs.TabsActivity">

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">

</android.support.v7.widget.Toolbar>

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

.java

También se crea un menu.xml y un fragment.xml que tampoco nos interesa, así que podemos borrarlos. Una vez eliminados, en la clase .java hay que eliminar los siguientes objetos y métodos:

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_borrarborrar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_borrarborrar, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}

En este punto, al compilar la TabsActivity se verá así:

Como sólo queremos mostrar dos pestañas, vamos al método getCount() y modificamos el valor return a 2:

@Override
public int getCount() {
// Show 2 total pages.
return 2;
}

Y en el método getPageTittle(int position), eliminamos el case 2:

@Override
public CharSequence getPageTitle(int position) {

String section = null;

switch (position) {
case 0:
section = "SECTION 1";
break;
case 1:
section = "SECTION 2";
break;
}
return section;
}

El aspecto ahora es el siguiente:

Como queremos mostrar en cada pestaña un fragment diferente, vamos a crearlos:

TabAFragment y TabBFragment

En el package que venimos usando: New -> Fragment -> Fragment (Blank) y creamos TabA y TabB.

xml

Ahora tenemos dos archivos xml fragment_tab_a y fragment_tab_b donde cambiaremos dentro del TextView el atributo text a “Estás en el fragment A” y “Estás en el fragment B”, según los respectivos xml.

.java

Eliminamos los métodos que no vamos a necesitar:

TabAFragment

package com.example.manuel.swipetabs;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TabAFragment extends Fragment {

public TabAFragment() {
// Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_a, container, false);
}
}

TabBFragment

package com.example.manuel.swipetabs;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TabBFragment extends Fragment {

public TabBFragment() {
// Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_b, container, false);
}
}

Para acabar, debemos ir a TabsActivity y haremos tres modificaciones:

Debe heredar de ActionBarActivity

Implementar la interfaz ActionBar.TabListener y ViewPager.OnPageChangeListener

Modificar método getItem(int position) en TabsActivity

Implementar las interfaces para los gestos tap y swipe

Al implementar la interfaz ActionBar.TabListener, Android Studio nos avisará que debemos incluir los métodos:

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {

}

@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {

El método que nos interesa desarrollar es onTabSelected, que es el que hará que el ViewPager cambie automáticamente de vista cuando el usuario haga “tap” en una pestaña. Para esto, al ViewPager le pasamos la posición de la pestaña que el usuario ha seleccionado.

mViewPager.setCurrentItem(tab.getPosition());

Y para la interfaz ViewPager.OnPageChangeListener, debemos incluir los métodos:

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
getSupportActionBar().setSelectedNavigationItem(position);
}

@Override
public void onPageScrollStateChanged(int state) {

}

El método que nos interesa es onPageSelected, que es el que hará que el ViewPager cambie automáticamente de vista cuando el usuario haga “swipe” en una pestaña:

getSupportActionBar().setSelectedNavigationItem(position);

Modificar método getItem(int position) en TabsActivity

Por último vamos a eliminar de la clase TabsActivity, la clase static PlaceHolderFragment y en el método getItem hacemos el siguiente switch case:

@Override
public Fragment getItem(int position) {

Fragment tabFragment = null;

switch (position){
case 0:
tabFragment = new TabAFragment();
break;
case 1:
tabFragment = new TabBFragment();
break;
}

return tabFragment;
}

Y esta es una forma sencilla para implementar SwipeTabs en la ActionBar gracias al IDE Android Studio.


Manuel Mato

Written by

Desde Mayo 2016 autodidacta de Java y Android