ViewPager'den ViewPager2'ye geçiş

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:

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 veya Fragment nesnesi ViewPager2 nesnesi bulunuyor. Çoğu durumda bu daha iyi bir seçenektir.
  • Bir FragmentManager nesnesi ve bir Lifecycle 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() yerine getItemCount() 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. Yeni createFragment() 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.
ziyaret edin.

Ö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:

  1. Sayfalara göz atmak için üst sınıfı RecyclerView.Adapter olarak değiştirin. Parçalar arasında sayfalama için FragmentStateAdapter.
  2. Parça tabanlı bağdaştırıcı sınıflarında oluşturucu parametrelerini değiştirin.
  3. getCount() yerine getItemCount() politikasını geçersiz kılın.
  4. Parça tabanlı bağdaştırıcıda getItem() yerine createFragment() 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

Videolar