Tworzenie widoków przesuwania z kartami za pomocą ViewPager2
Zadbaj o dobrą organizację dzięki kolekcji
Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
Widoki przesuwania umożliwiają poruszanie się między ekranami równorzędnymi, takimi jak karty, za pomocą
gestu poziomego lub przesunięcia palcem. Ten wzorzec nawigacji jest też nazywany
jako stronicowanie w poziomie.
Z tego tematu dowiesz się, jak utworzyć układ kart z widokami przesuwanymi, aby przejść na inną stronę
między kartami i jak wyświetlić pasek tytułu zamiast kart.
Wdróż widoki przesuwania
Widoki przesuwania można tworzyć za pomocą
ViewPager2.
Aby używać elementu ViewPager2 i kart, musisz dodać zależność
ViewPager2 i Material
Komponenty
do swojego projektu.
Aby skonfigurować układ za pomocą ViewPager2, dodaj element <ViewPager2> do
Układ XML. Jeśli na przykład każda strona w widoku przesuwania zajmuje całą
układ, układ będzie wyglądał tak:
Aby wstawić widoki podrzędne reprezentujące każdą stronę, połącz ten układ z komponentem
FragmentStateAdapter
Oto, jak za jego pomocą przesuwać kolekcję Fragment obiektów:
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{// The object is just an integer.putInt(ARG_OBJECT,position+1)}returnfragment}}privateconstvalARG_OBJECT="object"// Instances of this class are fragments representing a single// object in the 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();// The object is just an integer.args.putInt(DemoObjectFragment.ARG_OBJECT,position+1);fragment.setArguments(args);returnfragment;}@OverridepublicintgetItemCount(){return100;}}// Instances of this class are fragments representing a single// object in the 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)));}}
W poniższych sekcjach znajdziesz informacje o tym, jak dodać karty, aby ułatwić nawigację
między stronami.
Dodawanie kart za pomocą układu kart
TabLayout zapewnia
dzięki czemu karty mogą być wyświetlane w poziomie. W połączeniu z właściwością ViewPager2TabLayout może obsługiwać znajomy interfejs do poruszania się między stronami w
widok przesuwany.
Rysunek 1.TabLayout z 4 kartami.
Aby uwzględnić TabLayout w elemencie ViewPager2, dodaj element <TabLayout> powyżej
element <ViewPager2>:
Treść strony i umieszczone na niej fragmenty kodu podlegają licencjom opisanym w Licencji na treści. Java i OpenJDK są znakami towarowymi lub zastrzeżonymi znakami towarowymi należącymi do firmy Oracle lub jej podmiotów stowarzyszonych.
Ostatnia aktualizacja: 2025-07-27 UTC.
[[["Łatwo zrozumieć","easyToUnderstand","thumb-up"],["Rozwiązało to mój problem","solvedMyProblem","thumb-up"],["Inne","otherUp","thumb-up"]],[["Brak potrzebnych mi informacji","missingTheInformationINeed","thumb-down"],["Zbyt skomplikowane / zbyt wiele czynności do wykonania","tooComplicatedTooManySteps","thumb-down"],["Nieaktualne treści","outOfDate","thumb-down"],["Problem z tłumaczeniem","translationIssue","thumb-down"],["Problem z przykładami/kodem","samplesCodeIssue","thumb-down"],["Inne","otherDown","thumb-down"]],["Ostatnia aktualizacja: 2025-07-27 UTC."],[],[],null,["# Create swipe views with tabs using ViewPager2\n\nSwipe views let you navigate between sibling screens, such as tabs, with a\nhorizontal finger gesture, or *swipe* . This navigation pattern is also referred\nto as *horizontal paging*.\n\nThis topic teaches you how to create a tab layout with swipe views for switching\nbetween tabs and how to show a title strip instead of tabs.\n| **Note:** If your app already uses [`ViewPager`](/reference/kotlin/androidx/viewpager/widget/ViewPager), see [Migrate 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 [Material\nComponents](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 consumes the entire\nlayout, then your layout looks 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, hook this layout to a\n[`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 // The object is just an integer.\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 the 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 // The object is just an integer.\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 the 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**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: \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 lets users scroll through the list of tabs.\n\nFor additional design guidance for tab layouts, see the [Material Design\ndocumentation for\ntabs](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)"]]