As visualizações deslizáveis permitem navegar entre telas irmãs, como guias, com um gesto horizontal feito com o dedo (deslizar). Esse padrão de navegação também é conhecido como paginação horizontal. Este tópico ensina como criar um layout com visualizações deslizáveis para alternar entre guias, além de mostrar uma faixa de título em vez de guias.
Implementar visualizações deslizáveis
É possível criar visualizações deslizáveis usando o widget
ViewPager
do AndroidX.
Para usar um ViewPager
e guias, você precisa adicionar dependências no
ViewPager
e nos
Componentes do
Material Design (link em inglês)
do projeto.
Para configurar o layout com ViewPager
, adicione o elemento <ViewPager>
ao
layout XML. Por exemplo, se cada página na visualização deslizável usar
todo o layout, ele vai ficar assim:
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Para inserir visualizações secundárias que representem cada página, é preciso vincular esse layout a
um PagerAdapter
. Você pode
escolher entre dois tipos de adaptadores integrados:
FragmentPagerAdapter
: use esta opção ao navegar entre um pequeno número fixo de telas irmãs.FragmentStatePagerAdapter
: use esta opção ao navegar entre um número desconhecido de páginas.FragmentStatePagerAdapter
otimiza o uso da memória destruindo fragmentos à medida que o usuário navega.
Confira um exemplo de como usar FragmentStatePagerAdapter
para deslizar
por uma coleção de objetos Fragment
:
Kotlin
class CollectionDemoFragment : Fragment() { // When requested, this adapter returns a DemoObjectFragment // representing an object in the collection. private lateinit var demoCollectionPagerAdapter: DemoCollectionPagerAdapter private lateinit var viewPager: ViewPager override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.collection_demo, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { demoCollectionPagerAdapter = DemoCollectionPagerAdapter(childFragmentManager) viewPager = view.findViewById(R.id.pager) viewPager.adapter = demoCollectionPagerAdapter } } // Since this is an object collection, use a FragmentStatePagerAdapter, // NOT a FragmentPagerAdapter. class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = 100 override fun getItem(i: Int): Fragment { val fragment = DemoObjectFragment() fragment.arguments = Bundle().apply { // Our object is just an integer :-P putInt(ARG_OBJECT, i + 1) } return fragment } override fun getPageTitle(position: Int): CharSequence { return "OBJECT ${(position + 1)}" } } private const val ARG_OBJECT = "object" // Instances of this class are fragments representing a single // object in the collection. class DemoObjectFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { return inflater.inflate(R.layout.fragment_collection_object, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { arguments?.takeIf { it.containsKey(ARG_OBJECT) }?.apply { val textView: TextView = view.findViewById(android.R.id.text1) textView.text = getInt(ARG_OBJECT).toString() } } }
Java
public class CollectionDemoFragment extends Fragment { // When requested, this adapter returns a DemoObjectFragment // representing an object in the collection. DemoCollectionPagerAdapter demoCollectionPagerAdapter; ViewPager viewPager; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.collection_demo, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { demoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager()); viewPager = view.findViewById(R.id.pager); viewPager.setAdapter(demoCollectionPagerAdapter); } } // Since this is an object collection, use a FragmentStatePagerAdapter, // NOT a FragmentPagerAdapter. public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter { public DemoCollectionPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { Fragment fragment = new DemoObjectFragment(); Bundle args = new Bundle(); // Our object is just an integer :-P args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); fragment.setArguments(args); return fragment; } @Override public int getCount() { return 100; } @Override public CharSequence getPageTitle(int position) { return "OBJECT " + (position + 1); } } // Instances of this class are fragments representing a single // object in the collection. public class DemoObjectFragment extends Fragment { public static final String ARG_OBJECT = "object"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_collection_object, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Bundle args = getArguments(); ((TextView) view.findViewById(android.R.id.text1)) .setText(Integer.toString(args.getInt(ARG_OBJECT))); } }
As seções abaixo mostram como adicionar guias para facilitar a navegação entre páginas.
Adicionar guias usando um TabLayout
Um TabLayout
oferece
uma maneira de mostrar guias horizontalmente. Quando usado com um ViewPager
, um
TabLayout
fornece uma interface conhecida para navegar entre páginas em uma
visualização deslizável.
Figura 1. Um TabLayout
com quatro guias.
Para incluir um TabLayout
em um ViewPager
, adicione um elemento <TabLayout>
dentro do
elemento <ViewPager>
, conforme mostrado abaixo:
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.viewpager.widget.ViewPager>
Em seguida, use
setupWithViewPager()
para vincular o TabLayout
ao ViewPager
. As guias individuais em TabLayout
são preenchidas automaticamente com os títulos das páginas de PagerAdapter
:
Kotlin
class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) tabLayout.setupWithViewPager(viewPager) } ... } class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = 4 override fun getPageTitle(position: Int): CharSequence { return "OBJECT ${(position + 1)}" } ... }
Java
public class CollectionDemoFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); } ... } public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter { ... @Override public int getCount() { return 4; } @Override public CharSequence getPageTitle(int position) { return "OBJECT " + (position + 1); } ... }
Para outras orientações sobre o design de layouts de guias, consulte a documentação do Material Design para guias (link em inglês).