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çinPagerAdapter
değerini kullandığındaViewPager2
ileRecyclerView.Adapter
.ViewPager
, küçük bir sayfa içindeFragmentPagerAdapter
kullandığında sabit sayıda parça varsaViewPager2
ileFragmentStateAdapter
kullanın.ViewPager
, sayfa oluşturmak içinFragmentStatePagerAdapter
kullandığı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
FragmentActivity
nesnesi veyaFragment
nesnesiViewPager2
nesnesi bulunuyor. Çoğu durumda bu daha iyi bir seçenektir. - Bir
FragmentManager
nesnesi ve birLifecycle
nesnesi.
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.Adapter
olarak 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)