توسعه دهنده نرم افزار
معرفی اولیه ViewPager 2
نمیدونم اطلاع دارید یا نه اما گوگل 7 فوریه (18 بهمن) نسخه جدید ViewPager رو با نام 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()
}
}
و در نهایت خروجی کار به این صورت خواهد بود:
اسکرول عمودی
حالا میرسیم به قسمت جدید و کاربردی اسکرول عمودی در ViewPager
viewPager2.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%
اطلاعات بیشتر در اینجا
مطلبی دیگر از این انتشارات
استفاده از دیتا بایندینگ در ریسایکلرویو (اندروید)
مطلبی دیگر از این انتشارات
مجموعه تقلب مصاحبه شغلی برنامه نویس اندروید - قسمت اول
مطلبی دیگر از این انتشارات
کاتلین یا جاوا؟ مسئله این است.