ViewPager2, ViewPager kitaplığının gelişmiş bir sürümüdür.
ve ViewPager kullanımıyla ilgili sık karşılaşılan zorluklara çözüm bulabilirsiniz.
Uygulamanızda zaten ViewPager kullanılıyorsa şu konular hakkında daha fazla bilgi edinmek için bu sayfayı okuyun:
ViewPager2 hizmetine taşınıyor.
Uygulamanızda ViewPager2 kullanmak istiyor ve şu anda kullanmıyorsanız
ViewPager için kullanarak parçalar arasında kaydırma
ViewPager2 ve Şununla kaydırma görünümleri oluşturun:
daha fazla bilgi için ViewPager2'yi kullanın
ekleyebilirsiniz.
ViewPager2'ye taşımanın avantajları
Taşımanın birincil nedeni, ViewPager2 alan adının etkin olmasıdır
ViewPager değil, geliştirme desteği olduğunu unutmayın. Ancak ViewPager2 şu seçenekleri de sunuyor:
başka birçok avantaja da sahip olabilirsiniz.
Dikey yön desteği
ViewPager2, geleneksel yatay sayfanın yanı sıra dikey sayfalandırmayı da destekler
sayfalama. Bir ViewPager2 öğesi için dikey sayfalandırmayı ayarlayarak
android:orientation özelliği:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:orientation="vertical" />
Bu özelliği, setOrientation() yöntemidir.
Sağdan sola desteği
ViewPager2, sağdan sola (RTL) sayfalamayı destekler. Sağdan sola sayfalandırma etkin
uygun durumlarda, yerel ayara göre otomatik olarak
bir ViewPager2 öğesi için sağdan sola sayfalandırmayı etkinleştirmek üzere
android:layoutDirection özelliği:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layoutDirection="rtl" />
Bu özelliği, setLayoutDirection() yöntemidir.
Değiştirilebilir parça koleksiyonları
ViewPager2, değiştirilebilir bir parça koleksiyonu üzerinden sayfalandırmayı destekler.
arama
notifyDatasetChanged()
seçeneğini tıklayın.
Bu, uygulamanızın parça koleksiyonunu
gösterir ve ViewPager2, değiştirilen koleksiyonu doğru şekilde görüntüler.
Fark
ViewPager2, RecyclerView üzerine kurulmuştur,
Bu da onun
DiffUtil yardımcı programı
sınıfını kullanır. Bunun birçok faydası vardır ancak en önemlisi de
ViewPager2 nesne, veri kümesi değişiklik animasyonlarından yerel olarak yararlanır
RecyclerView sınıfından.
Uygulamanızı ViewPager2'ye taşıyın
Uygulamanızdaki ViewPager nesneyi ViewPager2 olarak güncellemek için şu adımları izleyin:
XML düzen dosyalarını güncelle
İlk olarak XML düzen dosyalarınızdaki ViewPager öğelerini
ViewPager2 öğeleri:
<!-- 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" />
Bağdaştırıcı sınıflarını güncelleme
ViewPager kullanırken bağdaştırıcı sınıfını şu şekilde genişletmeniz gerekti:
nesneye yeni sayfalar sağladı. Kullanım alanına bağlı olarak ViewPager kullanıldı
soyut sınıflardan oluşuyor. ViewPager2 yalnızca iki soyut sınıf kullanıyor.
ViewPager2 nesnesine dönüştürdüğünüz her ViewPager nesnesi için
bağdaştırıcı sınıfını, uygun soyut sınıfı aşağıdaki gibi genişletecek şekilde güncelleyin:
ViewPager, görüntülemeler arasında sayfa oluşturmak içinPagerAdapterdeğerini kullandığındaViewPager2ileRecyclerView.Adapter.ViewPager, küçük bir sayfa içindeFragmentPagerAdapterkullandığında sabit sayıda parça varsaViewPager2ileFragmentStateAdapterkullanın.ViewPager, sayfa oluşturmak içinFragmentStatePagerAdapterkullandığında büyük veya bilinmeyen sayıda parça varsaFragmentStateAdapteröğesiniViewPager2.
Oluşturucu parametreleri
FragmentPagerAdapter veya
FragmentStatePagerAdapter her zaman tek bir FragmentManager nesnesini kabul eder
olarak ayarlayın. FragmentStateAdapter uzatıldığında
ViewPager2 bağdaştırıcı sınıfı, oluşturucu için aşağıdaki seçeneklere sahipsiniz
parametresini kullanabilirsiniz:
- Buradaki
FragmentActivitynesnesi veyaFragmentnesnesiViewPager2nesnesi bulunuyor. Çoğu durumda bu daha iyi bir seçenektir. - Bir
FragmentManagernesnesi ve birLifecyclenesnesi.
Doğrudan RecyclerView.Adapter kaynağından devralınan görüntülemeye dayalı bağdaştırıcı sınıfları
oluşturucu parametresi gerektirmez.
Geçersiz kılma yöntemleri
Bağdaştırıcı sınıflarınızın, ViewPager2 için farklı yöntemleri de geçersiz kılması gerekir.
ViewPager için daha fazla:
getCount()yerinegetItemCount()değerini geçersiz kılın. Adın dışında bu yöntem değişmez.getItem()yerine, parçaya dayalıcreateFragment()değerini geçersiz kıl bağdaştırıcı sınıfları yer alır. YenicreateFragment()yönteminizin her zaman yerine, işlev her çağrıldığında yeni bir parça örneği sağlar tekrar kullanmanızı sağlar.
Özet
Özet olarak, ViewPager2 ile kullanılacak bir ViewPager bağdaştırıcı sınıfını dönüştürmek için
aşağıdaki değişiklikleri yapmanız gerekir:
- Sayfalara göz atmak için üst sınıfı
RecyclerView.Adapterolarak değiştirin. Parçalar arasında sayfalama içinFragmentStateAdapter. - Parça tabanlı bağdaştırıcı sınıflarında oluşturucu parametrelerini değiştirin.
getCount()yerinegetItemCount()politikasını geçersiz kılın.- Parça tabanlı bağdaştırıcıda
getItem()yerinecreateFragment()politikasını geçersiz kıl sınıflar.
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; } }
TabLayout arayüzlerini yeniden düzenleme
ViewPager2, TabLayout entegrasyonuyla ilgili değişiklikler sunuyor. Şu durumda:
şu anda yatay görüntülemek için TabLayout nesnesiyle bir ViewPager kullanın
gezinme sekmeleri için TabLayout nesnesini yeniden
ViewPager2 ile entegrasyon.
TabLayout, ViewPager2 alan adından ayrıldı ve artık şu ürünün bir parçası olarak kullanılabilir:
Materyal bileşenleri. Bu, onu kullanmak için web sitenize
build.gradle dosyanıza uygun bağımlılığı belirtin:
Eski
implementation "com.google.android.material:material:1.1.0-beta01"
Kotlin
implementation("com.google.android.material:material:1.1.0-beta01")
Ayrıca, TabLayout öğesinin hiyerarşisindeki konumunu da değiştirmeniz gerekir.
XML düzen dosyanız olur. ViewPager ile TabLayout öğesi
ViewPager öğesinin alt öğesi; ancak ViewPager2 ile TabLayout öğesi
ViewPager2 öğesinin hemen üstünde, aynı düzeyde belirtilir:
<!-- 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>
Son olarak, TabLayout nesnesini
ViewPager nesne algılandı. TabLayout ise kendi setupWithViewPager() değerini kullanır
ViewPager ile entegre etmek için kullanılan yöntem bir TabLayoutMediator
örneği ViewPager2 ile entegre edilir.
TabLayoutMediator nesnesi, sayfa başlıkları oluşturma görevini de yerine getirir
TabLayout nesnesi için oluşturulur. Bu da bağdaştırıcı sınıfının
getPageTitle() öğesini geçersiz kıl:
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(); } ... }
İç içe kaydırılabilir öğeleri destekleme
ViewPager2, iç içe yerleştirilmiş kaydırma görünümlerini yerel olarak desteklemez.
kaydırma görünümü, şunu içeren ViewPager2 nesnesiyle aynı yöne sahiptir:
somut olarak ortaya koyar. Örneğin, kaydırma tekerlekleri içindeki dikey kaydırma görünümünde
ViewPager2 nesnesidir.
Aynı yöne sahip bir ViewPager2 nesnesinin içindeki kaydırma görünümünü desteklemek için
araman lazım
requestDisallowInterceptTouchEvent(), ViewPager2 nesnesinde
bunun yerine iç içe yerleştirilmiş öğeyi kaydırmayı bekleyin. ViewPager2 iç içe geçmiş kaydırma
sample, bu problemi çok yönlü bir çözümle çözmenin bir yolunu gösterir.
özel sarmalayıcı düzeni hakkında daha fazla bilgi edinin.
Ek kaynaklar
ViewPager2 hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara göz atın.
Örnekler
- GitHub'da ViewPager2 örnekleri
Videolar
- Turning the Page: Migrate to ViewPager2 (Android Dev Summit '19)