Créer des vues à balayer avec des onglets à l'aide de ViewPager2
Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
Les vues à balayer vous permettent de naviguer entre des écrans frères tels que des onglets d'un geste horizontal du doigt ou balayage. Ce schéma de navigation est également appelé pagination horizontale. Cette rubrique vous explique comment créer une mise en page d'onglets avec des vues à balayer pour passer d'un onglet à l'autre, et comment afficher une barre de titre plutôt que des onglets.
Implémenter des vues à balayer
Vous pouvez créer des vues à balayer à l'aide du widget ViewPager2 d'AndroidX.
Pour utiliser ViewPager2 et les onglets, vous devez ajouter une dépendance à ViewPager2 et aux composants matériels de votre projet.
Pour configurer votre mise en page avec ViewPager2, ajoutez l'élément <ViewPager2> à votre mise en page XML. Par exemple, si chaque page de la vue à balayer doit utiliser l'intégralité de la mise en page, elle doit se présenter comme suit :
Pour insérer des vues enfants représentant chaque page, vous devez associer cette mise en page à un FragmentStateAdapter.
Voici comment l'utiliser pour balayer un ensemble d'objets Fragment :
Kotlin
classCollectionDemoFragment:Fragment(){// When requested, this adapter returns a DemoObjectFragment,// representing an object in the collection.privatelateinitvardemoCollectionAdapter:DemoCollectionAdapterprivatelateinitvarviewPager:ViewPager2overridefunonCreateView(inflater:LayoutInflater,container:ViewGroup?,savedInstanceState:Bundle?):View? {returninflater.inflate(R.layout.collection_demo,container,false)}overridefunonViewCreated(view:View,savedInstanceState:Bundle?){demoCollectionAdapter=DemoCollectionAdapter(this)viewPager=view.findViewById(R.id.pager)viewPager.adapter=demoCollectionAdapter}}classDemoCollectionAdapter(fragment:Fragment):FragmentStateAdapter(fragment){overridefungetItemCount():Int=100overridefuncreateFragment(position:Int):Fragment{// Return a NEW fragment instance in createFragment(int)valfragment=DemoObjectFragment()fragment.arguments=Bundle().apply{// Our object is just an integer :-PputInt(ARG_OBJECT,position+1)}returnfragment}}privateconstvalARG_OBJECT="object"// Instances of this class are fragments representing a single// object in our collection.classDemoObjectFragment:Fragment(){overridefunonCreateView(inflater:LayoutInflater,container:ViewGroup?,savedInstanceState:Bundle?):View{returninflater.inflate(R.layout.fragment_collection_object,container,false)}overridefunonViewCreated(view:View,savedInstanceState:Bundle?){arguments?.takeIf{it.containsKey(ARG_OBJECT)}?.apply{valtextView:TextView=view.findViewById(android.R.id.text1)textView.text=getInt(ARG_OBJECT).toString()}}}
Java
publicclassCollectionDemoFragmentextendsFragment{// When requested, this adapter returns a DemoObjectFragment,// representing an object in the collection.DemoCollectionAdapterdemoCollectionAdapter;ViewPager2viewPager;@Nullable@OverridepublicViewonCreateView(@NonNullLayoutInflaterinflater,@NullableViewGroupcontainer,@NullableBundlesavedInstanceState){returninflater.inflate(R.layout.collection_demo,container,false);}@OverridepublicvoidonViewCreated(@NonNullViewview,@NullableBundlesavedInstanceState){demoCollectionAdapter=newDemoCollectionAdapter(this);viewPager=view.findViewById(R.id.pager);viewPager.setAdapter(demoCollectionAdapter);}}publicclassDemoCollectionAdapterextendsFragmentStateAdapter{publicDemoCollectionAdapter(Fragmentfragment){super(fragment);}@NonNull@OverridepublicFragmentcreateFragment(intposition){// Return a NEW fragment instance in createFragment(int)Fragmentfragment=newDemoObjectFragment();Bundleargs=newBundle();// Our object is just an integer :-Pargs.putInt(DemoObjectFragment.ARG_OBJECT,position+1);fragment.setArguments(args);returnfragment;}@OverridepublicintgetItemCount(){return100;}}// Instances of this class are fragments representing a single// object in our collection.publicclassDemoObjectFragmentextendsFragment{publicstaticfinalStringARG_OBJECT="object";@Nullable@OverridepublicViewonCreateView(@NonNullLayoutInflaterinflater,@NullableViewGroupcontainer,@NullableBundlesavedInstanceState){returninflater.inflate(R.layout.fragment_collection_object,container,false);}@OverridepublicvoidonViewCreated(@NonNullViewview,@NullableBundlesavedInstanceState){Bundleargs=getArguments();((TextView)view.findViewById(android.R.id.text1)).setText(Integer.toString(args.getInt(ARG_OBJECT)));}}
Les sections suivantes expliquent comment ajouter des onglets pour faciliter la navigation entre les pages.
Ajouter des onglets avec TabLayout
Un TabLayout permet d'afficher les onglets horizontalement. Lorsqu'il est utilisé avec un ViewPager2, un TabLayout peut fournir une interface familière permettant de naviguer entre les pages en mode balayage.
Figure 1 : TabLayout avec quatre onglets
Pour inclure un TabLayout dans un ViewPager2, ajoutez un élément <TabLayout> au-dessus de l'élément <ViewPager2>, comme indiqué ci-dessous :
Le contenu et les exemples de code de cette page sont soumis aux licences décrites dans la Licence de contenu. Java et OpenJDK sont des marques ou des marques déposées d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/07/27 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 2025/07/27 (UTC)."],[],[],null,["# Create swipe views with tabs using ViewPager2\n\nSwipe views allow you to navigate between sibling screens, such as tabs, with a\nhorizontal finger gesture, or *swipe* . This navigation pattern is also referred\nto as *horizontal paging*. This topic teaches you how to create a tab layout\nwith swipe views for switching between tabs, along with how to show a title\nstrip instead of tabs.\n| **Note:** If your app already uses [`ViewPager`](/reference/kotlin/androidx/viewpager/widget/ViewPager), see [Migrate\n| from ViewPager to ViewPager2](/training/animation/vp2-migration).\n\nImplement Swipe Views\n---------------------\n\nYou can create swipe views using AndroidX's\n[`ViewPager2`](/reference/kotlin/androidx/viewpager2/widget/ViewPager2) widget.\nTo use ViewPager2 and tabs, you need to add a dependency on\n[ViewPager2](/jetpack/androidx/releases/viewpager2#androidx-deps) and on\n[Material Components](https://material.io/develop/android/docs/getting-started/)\nto your project.\n\nTo set up your layout with `ViewPager2`, add the `\u003cViewPager2\u003e` element to your\nXML layout. For example, if each page in the swipe view should consume the\nentire layout, then your layout should look like this: \n\n \u003candroidx.viewpager2.widget.ViewPager2\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:id=\"@+id/pager\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\" /\u003e\n\nTo insert child views that represent each page, you need to hook this layout to\na [`FragmentStateAdapter`](/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter).\nHere's how you might use it to swipe across a collection of `Fragment` objects: \n\n### Kotlin\n\n```kotlin\nclass CollectionDemoFragment : Fragment() {\n // When requested, this adapter returns a DemoObjectFragment,\n // representing an object in the collection.\n private lateinit var demoCollectionAdapter: DemoCollectionAdapter\n private lateinit var viewPager: ViewPager2\n\n override fun onCreateView(\n inflater: LayoutInflater,\n container: ViewGroup?,\n savedInstanceState: Bundle?\n ): View? {\n return inflater.inflate(R.layout.collection_demo, container, false)\n }\n\n override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n demoCollectionAdapter = DemoCollectionAdapter(this)\n viewPager = view.findViewById(R.id.pager)\n viewPager.adapter = demoCollectionAdapter\n }\n}\n\nclass DemoCollectionAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {\n\n override fun getItemCount(): Int = 100\n\n override fun createFragment(position: Int): Fragment {\n // Return a NEW fragment instance in createFragment(int)\n val fragment = DemoObjectFragment()\n fragment.arguments = Bundle().apply {\n // Our object is just an integer :-P\n putInt(ARG_OBJECT, position + 1)\n }\n return fragment\n }\n}\n\nprivate const val ARG_OBJECT = \"object\"\n\n// Instances of this class are fragments representing a single\n// object in our collection.\nclass DemoObjectFragment : Fragment() {\n\n override fun onCreateView(\n inflater: LayoutInflater,\n container: ViewGroup?,\n savedInstanceState: Bundle?\n ): View {\n return inflater.inflate(R.layout.fragment_collection_object, container, false)\n }\n\n override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n arguments?.takeIf { it.containsKey(ARG_OBJECT) }?.apply {\n val textView: TextView = view.findViewById(android.R.id.text1)\n textView.text = getInt(ARG_OBJECT).toString()\n }\n }\n}\n```\n\n### Java\n\n```java\npublic class CollectionDemoFragment extends Fragment {\n // When requested, this adapter returns a DemoObjectFragment,\n // representing an object in the collection.\n DemoCollectionAdapter demoCollectionAdapter;\n ViewPager2 viewPager;\n\n @Nullable\n @Override\n public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,\n @Nullable Bundle savedInstanceState) {\n return inflater.inflate(R.layout.collection_demo, container, false);\n }\n\n @Override\n public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {\n demoCollectionAdapter = new DemoCollectionAdapter(this);\n viewPager = view.findViewById(R.id.pager);\n viewPager.setAdapter(demoCollectionAdapter);\n }\n}\n\npublic class DemoCollectionAdapter extends FragmentStateAdapter {\n public DemoCollectionAdapter(Fragment fragment) {\n super(fragment);\n }\n\n @NonNull\n @Override\n public Fragment createFragment(int position) {\n // Return a NEW fragment instance in createFragment(int)\n Fragment fragment = new DemoObjectFragment();\n Bundle args = new Bundle();\n // Our object is just an integer :-P\n args.putInt(DemoObjectFragment.ARG_OBJECT, position + 1);\n fragment.setArguments(args);\n return fragment;\n }\n\n @Override\n public int getItemCount() {\n return 100;\n }\n}\n\n// Instances of this class are fragments representing a single\n// object in our collection.\npublic class DemoObjectFragment extends Fragment {\n public static final String ARG_OBJECT = \"object\";\n\n @Nullable\n @Override\n public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,\n @Nullable Bundle savedInstanceState) {\n return inflater.inflate(R.layout.fragment_collection_object, container, false);\n }\n\n @Override\n public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {\n Bundle args = getArguments();\n ((TextView) view.findViewById(android.R.id.text1))\n .setText(Integer.toString(args.getInt(ARG_OBJECT)));\n }\n}\n```\n\nThe following sections show how you can add tabs to help facilitate navigation\nbetween pages.\n\nAdd Tabs Using a TabLayout\n--------------------------\n\nA [`TabLayout`](/reference/com/google/android/material/tabs/TabLayout) provides\na way to display tabs horizontally. When used together with a `ViewPager2`, a\n`TabLayout` can provide a familiar interface for navigating between pages in a\nswipe view.\n\n**Figure 1:** A `TabLayout` with four tabs.\n\nTo include a `TabLayout` in a `ViewPager2`, add a `\u003cTabLayout\u003e` element above\nthe `\u003cViewPager2\u003e` element, as shown below: \n\n \u003cLinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\"\n android:orientation=\"vertical\"\u003e\n\n \u003ccom.google.android.material.tabs.TabLayout\n android:id=\"@+id/tab_layout\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"wrap_content\" /\u003e\n\n \u003candroidx.viewpager2.widget.ViewPager2\n android:id=\"@+id/pager\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"0dp\"\n android:layout_weight=\"1\" /\u003e\n\n \u003c/LinearLayout\u003e\n\nNext, create a\n[`TabLayoutMediator`](/reference/com/google/android/material/tabs/TabLayoutMediator)\nto link the `TabLayout` to the `ViewPager2`, and attach it as follows: \n\n### Kotlin\n\n```kotlin\nclass CollectionDemoFragment : Fragment() {\n ...\n override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n val tabLayout = view.findViewById(R.id.tab_layout)\n TabLayoutMediator(tabLayout, viewPager) { tab, position -\u003e\n tab.text = \"OBJECT ${(position + 1)}\"\n }.attach()\n }\n ...\n}\n```\n\n### Java\n\n```java\npublic class CollectionDemoFragment extends Fragment {\n ...\n @Override\n public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {\n TabLayout tabLayout = view.findViewById(R.id.tab_layout);\n new TabLayoutMediator(tabLayout, viewPager,\n (tab, position) -\u003e tab.setText(\"OBJECT \" + (position + 1))\n ).attach();\n }\n ...\n}\n```\n| **Note:** If you have a large or potentially infinite number of pages, set the `android:tabMode` attribute on your `TabLayout` to \"scrollable\". This prevents `TabLayout` from trying to fit all tabs on the screen at once and allows users to scroll through the list of tabs.\n\nFor additional design guidance for tab layouts, see the\n[Material Design documentation for tabs](https://material.io/design/components/tabs.html).\n\nAdditional resources\n--------------------\n\nTo learn more about `ViewPager2`, see the following additional resources.\n\n### Samples\n\n- [ViewPager2 samples](https://goo.gle/viewpager2-sample) on GitHub\n\n### Videos\n\n- [Turning the Page: Migrating to ViewPager2](https://www.youtube.com/watch?v=lAP6cz1HSzA) (Android Dev Summit '19)"]]