ViewPager থেকে ViewPager2-এ মাইগ্রেট করা

ViewPager2 হল ViewPager লাইব্রেরির একটি উন্নত ভার্সন যা উন্নত কার্যকারিতা অফার করে এবং ViewPager ব্যবহার করার সময় সাধারণ সমস্যার সমাধান করে। আপনার অ্যাপ আগে থেকেই ViewPager ব্যবহার করলে, ViewPager2-এ মাইগ্রেট করার ব্যাপারে আরও জানতে এই পৃষ্ঠাটি পড়ুন।

আপনি যদি নিজের অ্যাপে ViewPager2 ব্যবহার করতে চান এবং বর্তমানে ViewPager ব্যবহার না করেন, তাহলে আরও তথ্যের জন্য ViewPager2 ব্যবহার করে ফ্র্যাগমেন্টের মধ্যে স্লাইড করুন এবং ViewPager2 ব্যবহার করে ট্যাব সহ সোয়াইপ ভিউ তৈরি করুন নিবন্ধটি পড়ুন।

ViewPager2-এ মাইগ্রেট করার সুবিধা

মাইগ্রেট করার প্রাথমিক কারণ হল ViewPager2-এর জন্য অ্যাক্টিভ ডেভেলপমেন্ট সাপোর্ট পাওয়া যাচ্ছে এবং ViewPager-এর জন্য পাওয়া যাচ্ছে না। তবে, ViewPager2-এ আরও অনেক নির্দিষ্ট সুবিধা পাওয়া যায়।

উল্লম্ব ওরিয়েন্টেশন সংক্রান্ত সহায়তা

ViewPager2-এ চিরাচরিত অনুভূমিক পেজিংয়ের পাশাপাশি উল্লম্ব পেজিংয়ের সুবিধাও রয়েছে। আপনি ViewPager2 এলিমেন্টের জন্য উল্লম্ব পেজিং চালু করতে পারেন, এর জন্য আপনাকে android:orientation অ্যাট্রিবিউট সেট করতে হবে:

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

এছাড়াও, আপনি setOrientation() পদ্ধতি ব্যবহার করে প্রোগ্রাম্যাটিক্যালি এই অ্যাট্রিবিউট সেট করতে পারবেন।

ডানদিক থেকে বাঁদিকে লেখার সুবিধা

ViewPager2-এ ডানদিক থেকে বাঁদিকে (RTL) পেজিংয়ের সুবিধা আছে। লোকেল অনুযায়ী উপযুক্ত হলে RTL পেজিং অটোমেটিক চালু হয়ে যায়, তবে আপনি ViewPager2 এলিমেন্টের জন্য android:layoutDirection অ্যাট্রিবিউট সেট করে ম্যানুয়ালিও RTL পেজিং চালু করতে পারবেন:

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layoutDirection="rtl" />

এছাড়াও, আপনি setLayoutDirection() পদ্ধতি ব্যবহার করে প্রোগ্রাম্যাটিকভাবে এই অ্যাট্রিবিউট সেট করতে পারেন।

পরিবর্তনযোগ্য ফ্র্যাগমেন্ট সংগ্রহ

ViewPager2 ফ্র্যাগমেন্টের পরিবর্তনযোগ্য কালেকশনের মাধ্যমে পেজিং সমর্থন করে, কলিং notifyDatasetChanged() অন্তর্নিহিত কালেকশন পরিবর্তন হলে UI আপডেট করতে।

এর অর্থ হল, আপনার অ্যাপ রানটাইমে ফ্র্যাগমেন্ট সংগ্রহ ডায়নামিকভাবে পরিবর্তন করতে পারে এবং ViewPager2 পরিবর্তিত সংগ্রহ সঠিকভাবে দেখাবে।

DiffUtil

ViewPager2, RecyclerView-এর উপর ভিত্তি করে তৈরি করা হয়েছে, যার অর্থ হল, এটির কাছে DiffUtil ইউটিলিটি ক্লাসের অ্যাক্সেস আছে। এর ফলে অনেক সুবিধা পাওয়া যায়, তবে সবচেয়ে উল্লেখযোগ্য হল, ViewPager2 অবজেক্ট নেটিভভাবে RecyclerView ক্লাস থেকে ডেটাসেট পরিবর্তন অ্যানিমেশনের সুবিধা নেয়।

আপনার অ্যাপ ViewPager2-এ মাইগ্রেট করা

আপনার অ্যাপে ViewPager অবজেক্ট ViewPager2-এ আপডেট করতে এইসব ধাপ অনুসরণ করুন:

XML লেআউট ফাইল আপডেট করা

প্রথমে, আপনার XML লেআউট ফাইলের ViewPager এলিমেন্টগুলি 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" />

অ্যাডাপ্টার ক্লাস আপডেট করুন

ViewPager ব্যবহার করার সময়, আপনাকে অ্যাডাপ্টার ক্লাস এক্সটেন্ড করতে হত যা অবজেক্টে নতুন পৃষ্ঠা সরবরাহ করত। ব্যবহারের উপর নির্ভর করে, ViewPager তিনটি আলাদা অ্যাবস্ট্রাক্ট ক্লাস ব্যবহার করেছে। ViewPager2 শুধুমাত্র দুটি অ্যাবস্ট্রাক্ট ক্লাস ব্যবহার করে।

প্রতিটি ViewPager অবজেক্টের জন্য আপনি একটি ViewPager2 অবজেক্টে কনভার্ট করছেন, নিম্নলিখিত হিসাবে উপযুক্ত অ্যাবস্ট্রাক্ট ক্লাস প্রসারিত করতে অ্যাডাপ্টার ক্লাস আপডেট করুন:

  • ViewPager যখন ভিউয়ের মাধ্যমে পেজ করতে PagerAdapter ব্যবহার করে, তখন ViewPager2-এর সাথে RecyclerView.Adapter ব্যবহার করুন।
  • ViewPager যখন FragmentPagerAdapter ব্যবহার করে ছোট, নির্দিষ্ট সংখ্যক ফ্র্যাগমেন্টের মাধ্যমে পৃষ্ঠা তৈরি করে, তখন ViewPager2-এর সাথে FragmentStateAdapter ব্যবহার করুন।
  • ViewPager যখন FragmentStatePagerAdapter ব্যবহার করে বড় বা অজানা সংখ্যক ফ্র্যাগমেন্টের পৃষ্ঠাগুলি দেখে, তখন ViewPager2-এর সাথে FragmentStateAdapter ব্যবহার করুন।

কনস্ট্রাক্টর প্যারামিটার

FragmentPagerAdapter বা FragmentStatePagerAdapter থেকে ইনহেরিট করা ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাস সবসময় কনস্ট্রাক্টর প্যারামিটার হিসেবে একটি FragmentManager অবজেক্ট গ্রহণ করে। আপনি যখন FragmentStateAdapter-কে ViewPager2 অ্যাডাপ্টার ক্লাসের জন্য এক্সটেন্ড করেন, তখন আপনার কাছে কনস্ট্রাক্টর প্যারামিটারের জন্য পরিবর্তে নিম্নলিখিত বিকল্পগুলি থাকে:

  • FragmentActivity অবজেক্ট বা Fragment অবজেক্ট যেখানে ViewPager2 অবজেক্ট থাকে। বেশিরভাগ ক্ষেত্রে, এটিই হল আরও ভালো বিকল্প।
  • একটি FragmentManager অবজেক্ট এবং একটি Lifecycle অবজেক্ট।

RecyclerView.Adapter থেকে সরাসরি ইনহেরিট করা ভিউ-ভিত্তিক অ্যাডাপ্টার ক্লাসের জন্য কনস্ট্রাক্টর প্যারামিটারের প্রয়োজন হয় না।

ওভাররাইড পদ্ধতি

এছাড়াও, আপনার অ্যাডাপ্টার ক্লাসকে ViewPager-এর থেকে ViewPager2-এর জন্য বিভিন্ন পদ্ধতি ওভাররাইড করতে হবে:

  • getCount()-এর পরিবর্তে, getItemCount() ওভাররাইড করুন। নাম ছাড়া, এই পদ্ধতিতে কোনও পরিবর্তন করা হয়নি।
  • getItem()-এর পরিবর্তে, ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাসে createFragment() ওভাররাইড করুন। নিশ্চিত করুন যে আপনার নতুন createFragment() পদ্ধতিটি প্রতিবার ফাংশন কল করার সময় ইনস্ট্যান্স পুনরায় ব্যবহার করার পরিবর্তে সর্বদা একটি নতুন ফ্র্যাগমেন্ট ইনস্ট্যান্স সরবরাহ করে।

সারাংশ

সংক্ষেপে, ViewPager2-এর সাথে ব্যবহার করার জন্য ViewPager অ্যাডাপ্টার ক্লাস কনভার্ট করতে, আপনাকে নিম্নলিখিত পরিবর্তনগুলি করতে হবে:

  1. ভিউয়ের মাধ্যমে পেজিংয়ের জন্য সুপারক্লাস পরিবর্তন করে RecyclerView.Adapter করুন, অথবা ফ্র্যাগমেন্টের মাধ্যমে পেজিংয়ের জন্য FragmentStateAdapter করুন।
  2. ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাসে কনস্ট্রাক্টর প্যারামিটার পরিবর্তন করুন।
  3. getCount()-এর পরিবর্তে getItemCount() ওভাররাইড করুন।
  4. ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাসে getItem()-এর পরিবর্তে createFragment() ওভাররাইড করুন।

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()
}

জাভা

// 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 ইন্টারফেস রিফ্যাক্টর করা

ViewPager2, TabLayout ইন্টিগ্রেশনে পরিবর্তন নিয়ে এসেছে। আপনি যদি বর্তমানে নেভিগেশনের জন্য অনুভূমিক ট্যাব দেখাতে TabLayout অবজেক্ট সহ ViewPager ব্যবহার করেন, তাহলে ViewPager2-এর সাথে ইন্টিগ্রেশনের জন্য আপনাকে TabLayout অবজেক্ট রিফ্যাক্টর করতে হবে।

TabLayout-কে ViewPager2 থেকে আলাদা করা হয়েছে এবং এখন এটি মেটেরিয়াল কম্পোনেন্ট-এর অংশ হিসেবে উপলভ্য। এর অর্থ হল, এটি ব্যবহার করার জন্য, আপনাকে আপনার build.gradle ফাইলে উপযুক্ত ডিপেন্ডেন্সি যোগ করতে হবে:

গ্ৰুভি

implementation "com.google.android.material:material:1.1.0-beta01"

Kotlin

implementation("com.google.android.material:material:1.1.0-beta01")

এছাড়াও, আপনার XML লেআউট ফাইলের হায়ারার্কিতে TabLayout এলিমেন্টের লোকেশন পরিবর্তন করতে হবে। ViewPager-এর সাথে, TabLayout এলিমেন্টটি ViewPager এলিমেন্টের চাইল্ড হিসেবে ঘোষণা করা হয়; কিন্তু ViewPager2-এর সাথে, TabLayout এলিমেন্টটি সরাসরি ViewPager2 এলিমেন্টের উপরে, একই লেভেলে ঘোষণা করা হয়:

<!-- 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>

সবশেষে, আপনাকে অবশ্যই সেই কোডটি আপডেট করতে হবে যা TabLayout অবজেক্টকে ViewPager অবজেক্টের সাথে অ্যাটাচ করে। TabLayout, ViewPager-এর সাথে ইন্টিগ্রেট করার জন্য নিজস্ব setupWithViewPager() পদ্ধতি ব্যবহার করলেও, ViewPager2-এর সাথে ইন্টিগ্রেট করার জন্য এটির TabLayoutMediator ইনস্ট্যান্স প্রয়োজন।

TabLayoutMediator অবজেক্টটি TabLayout অবজেক্টের জন্য পৃষ্ঠার টাইটেল তৈরি করার কাজও পরিচালনা করে, যার অর্থ হল অ্যাডাপ্টার ক্লাসকে 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()
    }
    ...
}

জাভা

// 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();
    }
    ...
}

নেস্টেড স্ক্রল করা যায় এমন এলিমেন্ট কাজ করে

ViewPager2-এ নেটিভভাবে নেস্টেড স্ক্রল ভিউ কাজ করে না, যদি স্ক্রল ভিউয়ের ওরিয়েন্টেশন ViewPager2 অবজেক্টের ওরিয়েন্টেশনের সাথে একই হয়। যেমন, উল্লম্বভাবে-সাজানো ViewPager2 অবজেক্টের মধ্যে উল্লম্ব স্ক্রল ভিউয়ের জন্য স্ক্রল করা কাজ করবে না।

একই ওরিয়েন্টেশন সহ ViewPager2 অবজেক্টের মধ্যে স্ক্রল ভিউয়ের সুবিধা দিতে, আপনি যখন নেস্টেড এলিমেন্ট স্ক্রল করতে চাইবেন, তখন আপনাকে ViewPager2 অবজেক্টে requestDisallowInterceptTouchEvent() কল করতে হবে। ViewPager2 নেস্টেড স্ক্রলিং স্যাম্পেল একটি বহুমুখী কাস্টম র‍্যাপার লেআউট-এর মাধ্যমে এই সমস্যার সমাধান করার একটি উপায় দেখায়।

অতিরিক্ত রিসোর্স

ViewPager2 সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।

নমুনা

ভিডিও