ViewPager2 adalah versi peningkatan library ViewPager yang menawarkan
fungsi yang disempurnakan dan menangani kesulitan umum dalam menggunakan ViewPager.
Jika aplikasi Anda sudah menggunakan ViewPager, baca halaman ini untuk mempelajari lebih lanjut
yang dimigrasikan ke ViewPager2.
Jika Anda ingin menggunakan ViewPager2 di aplikasi dan saat ini tidak menggunakannya
ViewPager, baca Bergeser antar-fragmen menggunakan
ViewPager2 dan Membuat tampilan geser dengan
tab yang menggunakan ViewPager2 untuk informasi lainnya
tidak akurat atau tidak sesuai.
Manfaat migrasi ke ViewPager2
Alasan utama untuk melakukan migrasi adalah karena ViewPager2 menjadi aktif
dukungan pengembangan dan ViewPager tidak. Namun, ViewPager2 juga menawarkan
beberapa keuntungan spesifik lainnya.
Dukungan orientasi vertikal
ViewPager2 mendukung paging vertikal selain horizontal tradisional
{i>paging<i}. Anda dapat mengaktifkan paging vertikal untuk elemen ViewPager2 dengan menyetel
Atribut android:orientation:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:orientation="vertical" />
Anda juga dapat menetapkan atribut ini secara terprogram menggunakan setOrientation() .
Dukungan kanan-ke-kiri
ViewPager2 mendukung penjelajahan halaman kanan-ke-kiri (RTL). Paging RTL diaktifkan
secara otomatis jika perlu berdasarkan lokalitas, tetapi Anda juga dapat secara manual
aktifkan paging RTL untuk elemen ViewPager2 dengan menyetel elemen
Atribut android:layoutDirection:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layoutDirection="rtl" />
Anda juga dapat menetapkan atribut ini secara terprogram menggunakan setLayoutDirection() .
Kumpulan fragmen yang dapat diubah
ViewPager2 mendukung paging melalui koleksi fragmen yang dapat dimodifikasi,
menelepon
notifyDatasetChanged()
untuk mengupdate UI saat koleksi yang mendasarinya berubah.
Ini berarti bahwa aplikasi Anda dapat memodifikasi pengumpulan fragmen secara dinamis di
runtime, dan ViewPager2 akan menampilkan koleksi yang diubah dengan benar.
DiffUtil
ViewPager2 dibuat di RecyclerView,
artinya, ia memiliki akses ke
Utilitas DiffUtil
. Hal ini memberikan beberapa manfaat, tetapi yang terutama berarti bahwa
Objek ViewPager2 secara native memanfaatkan animasi perubahan set data
dari class RecyclerView.
Memigrasikan aplikasi Anda ke ViewPager2
Ikuti langkah-langkah berikut untuk memperbarui objek ViewPager di aplikasi Anda ke ViewPager2:
Memperbarui file tata letak XML
Pertama, ganti elemen ViewPager dalam file tata letak XML Anda dengan
Elemen ViewPager2:
<!-- A ViewPager element -->
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- A ViewPager2 element -->
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Memperbarui class adaptor
Saat menggunakan ViewPager, Anda harus memperluas class adaptor yang
halaman baru yang disediakan ke objek. Bergantung pada kasus penggunaannya, ViewPager digunakan
tiga class abstrak yang berbeda. ViewPager2 hanya menggunakan dua class abstrak.
Untuk setiap objek ViewPager yang Anda konversi menjadi objek ViewPager2,
update class adaptor untuk memperluas class abstrak yang sesuai sebagai berikut:
- Saat
ViewPagermenggunakanPagerAdapteruntuk menelusuri penayangan, gunakanRecyclerView.AdapterdenganViewPager2. - Saat
ViewPagermenggunakanFragmentPagerAdapteruntuk menelusuri halaman yang jumlah fragmen tetap, gunakanFragmentStateAdapterdenganViewPager2. - Saat
ViewPagermenggunakanFragmentStatePagerAdapteruntuk menelusuri fragmen berukuran besar atau tidak diketahui, gunakanFragmentStateAdapterdenganViewPager2.
Parameter konstruktor
Class adaptor berbasis fragmen yang mewarisi dari FragmentPagerAdapter atau
FragmentStatePagerAdapter selalu menerima satu objek FragmentManager
sebagai parameter konstruktor. Saat Anda memperluas FragmentStateAdapter untuk
Class adaptor ViewPager2, Anda memiliki opsi berikut untuk konstruktor
parameter sebagai gantinya:
- Objek
FragmentActivityatau objekFragmenttempat ObjekViewPager2berada. Pada umumnya, opsi ini akan lebih baik. - Objek
FragmentManagerdan objekLifecycle.
Class adaptor berbasis tampilan yang mewarisi langsung dari RecyclerView.Adapter melakukan
tidak memerlukan parameter konstruktor.
Mengganti metode
Class adaptor Anda juga perlu mengganti berbagai metode untuk ViewPager2
dibandingkan untuk ViewPager:
- Ganti
getItemCount(), bukangetCount(). Selain nama, metode ini tidak berubah. - Ganti
createFragment()dalam aplikasi berbasis fragmen, bukangetItem()class adaptor. Pastikan metodecreateFragment()baru Anda selalu menyediakan instance fragmen baru setiap kali fungsi dipanggil, bukan menggunakan kembali instance.
Ringkasan
Singkatnya, untuk mengonversi class adaptor ViewPager agar dapat digunakan dengan ViewPager2,
Anda harus membuat perubahan berikut:
- Ubah superclass menjadi
RecyclerView.Adapteruntuk melakukan paging melalui tampilan, atauFragmentStateAdapteruntuk melakukan paging melalui fragmen. - Ubah parameter konstruktor dalam class adaptor berbasis fragmen.
- Ganti
getItemCount(), bukangetCount(). - Mengganti
createFragment(), bukangetItem()dalam adaptor berbasis fragmen Google Cloud Platform.
Kotlin
// A simple ViewPager adapter class for paging through fragments class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = NUM_PAGES override fun getItem(position: Int): Fragment = ScreenSlidePageFragment() } // An equivalent ViewPager2 adapter class class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { override fun getItemCount(): Int = NUM_PAGES override fun createFragment(position: Int): Fragment = ScreenSlidePageFragment() }
Java
// A simple ViewPager adapter class for paging through fragments public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { public ScreenSlidePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return new ScreenSlidePageFragment(); } @Override public int getCount() { return NUM_PAGES; } } // An equivalent ViewPager2 adapter class private class ScreenSlidePagerAdapter extends FragmentStateAdapter { public ScreenSlidePagerAdapter(FragmentActivity fa) { super(fa); } @Override public Fragment createFragment(int position) { return new ScreenSlidePageFragment(); } @Override public int getItemCount() { return NUM_PAGES; } }
Faktorkan ulang antarmuka TabLayout
ViewPager2 memperkenalkan perubahan pada integrasi TabLayout. Jika Anda
saat ini menggunakan ViewPager dengan objek TabLayout untuk menampilkan horizontal
untuk navigasi, Anda perlu memfaktorkan ulang objek TabLayout untuk
integrasi dengan ViewPager2.
TabLayout telah dipisahkan dari ViewPager2 dan sekarang tersedia sebagai bagian dari
Komponen material. Ini berarti bahwa untuk menggunakannya, Anda perlu menambahkan
dependensi yang sesuai untuk file build.gradle Anda:
Groovy
implementation "com.google.android.material:material:1.1.0-beta01"
Kotlin
implementation("com.google.android.material:material:1.1.0-beta01")
Anda juga perlu mengubah lokasi elemen TabLayout dalam hierarki
file tata letak XML Anda. Dengan ViewPager, elemen TabLayout dideklarasikan sebagai
turunan dari elemen ViewPager; tetapi dengan ViewPager2, elemen TabLayout
dideklarasikan langsung di atas elemen ViewPager2, pada tingkat yang sama:
<!-- A ViewPager element with a TabLayout -->
<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>
<!-- A ViewPager2 element with a TabLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Terakhir, Anda harus mengupdate kode yang melampirkan objek TabLayout ke
Objek ViewPager. Meskipun TabLayout menggunakan setupWithViewPager()-nya sendiri
untuk berintegrasi dengan ViewPager, diperlukan TabLayoutMediator
untuk diintegrasikan dengan ViewPager2.
Objek TabLayoutMediator juga menangani tugas untuk membuat judul halaman
untuk objek TabLayout, yang berarti bahwa class adaptor tidak perlu
ganti getPageTitle():
Kotlin
// Integrating TabLayout with ViewPager 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)}" } ... } // Integrating TabLayout with ViewPager2 class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = "OBJECT ${(position + 1)}" }.attach() } ... }
Java
// Integrating TabLayout with ViewPager 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); } ... } // Integrating TabLayout with ViewPager2 public class CollectionDemoFragment : Fragment() { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText("OBJECT " + (position + 1)) ).attach(); } ... }
Dukung elemen bertingkat yang dapat di-scroll
ViewPager2 tidak mendukung tampilan scroll bertingkat secara native jika
tampilan scroll memiliki orientasi yang sama dengan objek ViewPager2 yang berisi
anotasi. Misalnya, men-scroll tidak akan berfungsi untuk tampilan scroll vertikal di dalam
objek ViewPager2 berorientasi vertikal.
Untuk mendukung tampilan scroll di dalam objek ViewPager2 dengan orientasi yang sama,
kamu harus panggil
requestDisallowInterceptTouchEvent() pada objek ViewPager2 saat Anda
kita akan menggulir elemen tersarang. Scrolling bertingkat ViewPager2
contoh menunjukkan satu cara untuk menyelesaikan masalah ini dengan
tata letak wrapper kustom.
Referensi lainnya
Untuk mempelajari ViewPager2 lebih lanjut, baca referensi tambahan berikut ini.
Contoh
- Contoh ViewPager2 di GitHub
Video
- Turning the Page: Migrating to ViewPager2 (Android Dev Summit '19)