As visualizações deslizáveis permitem que você navegue entre telas irmãs, como guias, com um gesto horizontal com o dedo ou deslizando. 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 o ViewPager e guias, você precisa adicionar uma dependência no ViewPager e nos Componentes do Material (link em inglês) do projeto.
Para configurar o layout com ViewPager
, adicione o <ViewPager>
ao layout XML. Por exemplo, se cada página na visualização deslizável consumir todo o layout, ele 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 paginar um número desconhecido de páginas.FragmentStatePagerAdapter
otimiza o uso da memória destruindo fragmentos à medida que o usuário navega.
Por exemplo, veja 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, // and 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 our 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, // and 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 our 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 a seguir mostram como adicionar guias para facilitar a navegação entre páginas.
Adicionar guias usando um TabLayout
Um TabLayout
oferece uma maneira de exibir guias horizontalmente. Quando usado junto com ViewPager
, um TabLayout
pode fornecer uma interface familiar 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).