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
ViewPager
menggunakanPagerAdapter
untuk menelusuri penayangan, gunakanRecyclerView.Adapter
denganViewPager2
. - Saat
ViewPager
menggunakanFragmentPagerAdapter
untuk menelusuri halaman yang jumlah fragmen tetap, gunakanFragmentStateAdapter
denganViewPager2
. - Saat
ViewPager
menggunakanFragmentStatePagerAdapter
untuk menelusuri fragmen berukuran besar atau tidak diketahui, gunakanFragmentStateAdapter
denganViewPager2
.
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
FragmentActivity
atau objekFragment
tempat ObjekViewPager2
berada. Pada umumnya, opsi ini akan lebih baik. - Objek
FragmentManager
dan 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.Adapter
untuk melakukan paging melalui tampilan, atauFragmentStateAdapter
untuk 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)