معرفی اولیه ViewPager 2

نمیدونم اطلاع دارید یا نه اما گوگل 7 فوریه (18 بهمن) نسخه جدید ViewPager رو با نام ViewPager 2 معرفی کرد و خب خالی از لطف نیست اگر بعضی از تغییرات این نسخه با نسخه قبلی رو با هم بررسی کنیممعرفی اولیه ViewPager 2 ویژگی های جدید- قابلیت راست به چپ کردن لایه ها- ساپورت کردن از Orientation عمودی- PageChangeListener بهترچه چیزایی تغییر کرده؟- PagerAdapter جایگزین شده با RecyclerView.Adapter (فوق العاده نیست؟!!!)- FragmentStatePagerAdapter هم جایگزین شده با FragmentStateAdapterنکته مهمViewPager 2 در واقع برای Android X معرفی شده و برای استفاده از اون باید پروژه تون رو با کامپونتت های Android X سازگار کنید؛ حالا چجوری باید به Android X مهاجرت کرد؟(کلیک کنید)نصببرای استفاده از ViewPager 2 باید ابتدا کتابخونه اون رو به فایل Build.gradle ماژول اپ وارد dependencies { implementation "androidx.viewpager2:viewpager2:1.0.0-alpha01" }پروژه رو Sync کنید تا کتابخونه دانلود بشه(نیاز به VPN)پیاده سازی- ViewPager 2 رو به لایه xml صفحه ای که میخواید داخلش از اون استفاده کنید، اضافه کنید<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent"/>- همونطوری که در بالا گفتم حالا میتونید برای اداپتر ViewPager 2 از RecyclerView استفاده کنید که یه چیز فوق العاده لذت بخشه! برای این کار باید اول لایوت هر آیتم ViewPager 2 رو بسازیم(مثلا نام لایه ما item_page.xml هستش) :<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/tvTitle" android:textColor="@android:color/white" android:layout_width="wrap_content" android:layout_centerInParent="true" tools:text= "item" android:textSize="32sp" android:layout_height="wrap_content" /> </RelativeLayout>- حالا ما نیاز داریم یک آداپتر برای ویو پیجرمون بسازیم (دقیقا مثل RecyclerView)؛ کلاس آداپترمون ViewPagerAdapter.kt:class ViewPagerAdapter : RecyclerView.Adapter<PagerVH>() { privateval colors = intArrayOf( android.R.color.black, android.R.color.holo_red_light, android.R.color.holo_blue_dark, android.R.color.holo_purple ) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagerVH = PagerVH(LayoutInflater.from(parent.context).inflate(R.layout.item_page, parent, false)) override fun getItemCount(): Int = colors.size override fun onBindViewHolder(holder: PagerVH, position: Int) = holder.itemView.run { tvTitle.text = "item $position" container.setBackgroundResource(colors[position]) } } class PagerVH(itemView: View) : RecyclerView.ViewHolder(itemView)- حالا در مرحله آخر کافیه آداپترمون رو روی ViewPager ــی که در لایوت صفحه اصلیمون اضافه کردیم ست بکنیم.class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewPager2.adapter = ViewPagerAdapter() } }و در نهایت خروجی کار به این صورت خواهد بود:نتیجه کاراسکرول عمودیحالا میرسیم به قسمت جدید و کاربردی اسکرول عمودی در ViewPagerviewPager2.orientation = ViewPager2.ORIENTATION_VERTICALنتیجه به این شکل خواهد بود:نتیجه اسکرول عمودیاستفاده از FragmentStateAdapterشما همچنین میتونید فرگمنت هارو با روش قدیمی ViewPager هم بسازید؛ برای این کار باید از FragmentStateAdapter استفاده کنیم:- ابتدا فرگمنت رو میسازیم:class PagerFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.item_page, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { arguments?.let { container.setBackgroundResource(it.getInt("color")) tvTitle.text = "Item ${it.getInt("position")}" } } }- حالا باید یک آداپتر برای مدیریت فرگمنت (ها) مون بسازیم: class ViewPagerFragmentStateAdapter(fm: FragmentManager) : FragmentStateAdapter(fm){ privateval colors = intArrayOf( android.R.color.black, android.R.color.holo_red_light, android.R.color.holo_blue_dark, android.R.color.holo_purple ) override fun getItem(position: Int): Fragment = PagerFragment().apply { arguments = bundleOf( "color" to colors[position], "position" to position ) } override fun getItemCount(): Int = colors.size }- و در مرحله آخر باید آداپترمون رو روی ViewPager ست کنیم:viewPager2.adapter = ViewPagerFragmentStateAdapter(supportFragmentManager)متد ChangeCallback خیلی آساندر ViewPager نسخه قبل ما با استفاده از متد ChangeListener کار های مثل تغییرات Page یا Event های Scroll شدن رو مدیریت می کردیم این کار مشکلاتی داشت مثلا ما مجبور بودیم همه متد های ScrollStateChanged، dScrolled و Selected رو پیاده سازی می کردیم فارغ از اینکه با کدومشون کار داریم!! مثل زیر:oldViewPager.addChangeListener(object:ViewPager.ChangeListener{ override fun ScrollStateChanged(state: Int) { // useless } override fun Scrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { // useless too } override fun Selected(position: Int) { // useful } })خبر خوب اینه که این روزا رفتن و دیگه نیازی به این کار نیست :) ما حالا با استفاده از ViewPager 2 و با متد ChangeCallback که یک abstract class هستش و البته شامل متد های non-abstract هست.یعنی چی؟ یعنی اینکه ما فقط متدی رو پیاده سازی میکنیم که نیاز داریم:viewPager2.registerChangeCallback(object : ViewPager2.ChangeCallback() { override fun Selected(position: Int) { super.Selected(position) // No boilerplate, only useful } })هشدارکتابخونه ViewPager 2 هنوز در نسخه alpha(غیر stable) هستش؛ بعضی از ویژگی های نسخه قبلی در نسخه جدید به درستی کار نمیکنن یا ناقص هستند و خب بزودی و در نسخه Stable احتمالا این مشکلات برطرف میشن؛ خود داکیومنت گوگل این موارد رو معرفی کرده:- ClipToPadding- No implementation for integrating with TabLayout- no offscreen limit control- (no pageWidth setter (forced 100%/100%اطلاعات بیشتر در اینجامنبع