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 অ্যাডাপ্টার ক্লাস কনভার্ট করতে,
আপনাকে নিম্নলিখিত পরিবর্তনগুলি করতে হবে:
- ভিউয়ের মাধ্যমে পেজিংয়ের জন্য সুপারক্লাস পরিবর্তন করে
RecyclerView.Adapterকরুন, অথবা ফ্র্যাগমেন্টের মাধ্যমে পেজিংয়ের জন্যFragmentStateAdapterকরুন। - ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাসে কনস্ট্রাক্টর প্যারামিটার পরিবর্তন করুন।
getCount()-এর পরিবর্তেgetItemCount()ওভাররাইড করুন।- ফ্র্যাগমেন্ট-ভিত্তিক অ্যাডাপ্টার ক্লাসে
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 সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।
নমুনা
- GitHub-এ ViewPager2 স্যাম্পেল
ভিডিও
- Turning the Page: Migrating to ViewPager2 (Android Dev Summit '19)