Como Exibir Tabs Utilizando TabLayout e ViewPager no Android
Autor: Rosana Oliveira | Publicado: 2015-12-02T17:45:00-02:00

A forma de programação para exibir Tabs no Android vem mudando em cada lançamento de uma nova versão do sistema operacional. A partir da API 22 do Android Lollipop surgiu uma nova forma de exibir telas com Tab, que possuem o efeito chamado de "Swipe". Este efeito permite visualizar cada Tab com um movimento horizontal na tela.

Mas e se quisermos utilizar a Tab no formato tradicional onde cada Tab é acessada clicando-se na aba. Ainda é possível montar este layout utilizando as classes&nbsp;TabLayout&nbsp;e&nbsp;ViewPager.

Para mostrar como podemos montar a tela com a apresentação tradicional de tabs, desenvolvi um projeto que exibe três Tabs de acordo com o apresentado na Figura 1.



Figura 1



O projeto é composto da tela principal MainActivity,&nbsp;das telas das Tabs a Tab1Fragment, Tab2Fragment e Tab3Fragment e da classe TabPagerAdapter utilizada para gerenciar os Fragments, neste caso as classes das Tabs.

O arquivo de layout da tela principal activity_main.xml deve ser composto de um TabLayout e de um ViewPager:
<!-- HTML generated using hilite.me -->

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:padding="4dip"
    android:gravity="center_horizontal"
    android:layout_width="match_parent" android:layout_height="match_parent"&gt;

    &lt;android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" /&gt;

    &lt;android.support.v4.view.ViewPager&nbsp;
xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"&gt;

    &lt;/android.support.v4.view.ViewPager&gt;

&lt;/LinearLayout&gt;



No widget TabLayout o atributo&nbsp;tabMode&nbsp;foi configurado como fixed, para que as Tabs fiquem fixadas e respondam ao clique na aba, ao invés do movimento de "swipe".

As telas de Tabs possuem cada uma somente um TextView para exibir um texto. Segue o código do arquivo xml que foi utilizado para construir a Tab1Fragment.


&lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"&nbsp;
android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp"
    tools:context="br.com.romarconsultoria.tabexemplo.Tab1Fragment"&gt;

    &lt;TextView android:layout_width="match_parent"&nbsp;
android:layout_height="match_parent"
        android:text="Tela da Tab1"
        android:textSize="25sp"/&gt;

&lt;/FrameLayout&gt;




As classes Tab1Fragment, Tab2Fragment e Tab3Fragment são utilizadas para exibir o conteúdo de cada Tab. Segue o código da classe Tab1Fragment. As classes Tab2Fragment e Tab3Fragment são similares.

<!-- HTML generated using hilite.me -->

public class Tab1Fragment extends Fragment {

    public static Tab1Fragment newInstance() {
        Tab1Fragment fragment = new Tab1Fragment();
        return fragment;
    }

    public Tab1Fragment() {
        // Deve existir um construtor vazio
        // na classe que estende um Fragment
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

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

}



Para gerenciar as Tabs é necessário criar uma classe que estende a classe FragmentPagerAdapter responsável pela paginação das Tabs. &nbsp;Criei a classe TabsPagerAdapter e implementei os métodos:


getItem(int): Retorna a tab que deve ser exibida de acordo com a posição selecionada.
getCount(): Retorna o número total de tabs.
getPageTitle(int): Retorna o título da tab de acordo com a posição selecionada.&nbsp;


Os métodos getItem(int) e getCount() são obrigatórios na classe que estende a classe FragmentPagerAdapter.

<!-- HTML generated using hilite.me -->

public class TabsPagerAdapter extends FragmentPagerAdapter {
    private static final int NUM_TABS = 3;

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

    @Override
    public Fragment getItem(int position) {
        switch(position){
            case 0:
                return Tab1Fragment.newInstance();
            case 1:
                return Tab2Fragment.newInstance();
            default:
                return Tab3Fragment.newInstance();
        }
    }

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

    @Override
    public CharSequence getPageTitle(int position) {

        if (position == 0){
            return "Tab 1";
        }

        if (position == 1){
            return "Tab 2";
        }

        return "Tab 3";
    }
}


A classe MainActivity inicia o TabLayout, o ViewPager e configura o adaptador que as tabs devem utilizar.

<!-- HTML generated using hilite.me -->

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Tabs
        TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        TabsPagerAdapter adapter = new TabsPagerAdapter(getSupportFragmentManager());

        pager.setAdapter(adapter);
        tabs.setupWithViewPager(pager);
    }
}


Pronto agora já é possível navegar nas tabs no formato fixo.