
7 рдлрд░рд╡рд░реА, 2019 рдХреЛ рдЬреНрдпрд╛рджрд╛ рд╕рдордп рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, Google рдиреЗ Android ViewPager2 рдХрд╛ рдЕрд▓реНрдлрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд┐рдпрд╛ред рдЗрд╕ рд░рд┐рд▓реАрдЬ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ ред рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ ViewPager2 рдХреНрдпрд╛ рд╣реИред
рдирдИ рд╕реБрд╡рд┐рдзрд╛рдПрдБ
- рджрд╛рдПрдВ рд╕реЗ рдмрд╛рдПрдВ рддрдХ рдХрд╛ рд╕рдорд░реНрдерди рд▓реЗрдЖрдЙрдЯ,
- рд╕рдорд░реНрдерди рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕,
- рдмреЗрд╣рддрд░
PageChangeListener
ред
рдХреНрдпрд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ?
ViewPager2 Android X рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ Android X рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдо рдЗрд╕ рдирдП ViewPager2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВ
рдирд┐рдореНрди рдирд┐рд░реНрднрд░рддрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕реНрддрд░ build.gradle
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
dependencies { implementation "androidx.viewpager2:viewpager2:1.0.0-alpha01" }
рдЙрд╕рдХреЗ рдмрд╛рдж, рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░реЗрдВред
рд╕рдорд╛рдпреЛрдЬрди
рдЕрдкрдиреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдпрд╛ рдЯреБрдХрдбрд╝реЗ рдореЗрдВ ViewPager2
рд╡рд┐рдЬреЗрдЯ рдЬреЛрдбрд╝реЗрдВ:
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent"/>
рдЪрд▓рд┐рдП рдЙрд╕ рдкреЗрдЬ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдБ рдЬреЛ ViewPager2 рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
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>
рдЕрдЧрд▓рд╛ рд╣рдореЗрдВ ViewPager2 рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдбреЗрдкреНрдЯрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо RecyclerView.Adapter
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдпрд╣ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ?
ViewPagerAdapter.kt
class ViewPagerAdapter : RecyclerView.Adapter<PagerVH>() { private val 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)
рдпрд╣ рдПрдХ рд╣реА рдПрдбреЗрдкреНрдЯрд░ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдПрдХ рдирд┐рдпрдорд┐рдд RecyclerView рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рд┐рд░реНрдл ViewPager2 рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЕрдВрддрд┐рдо рдЪрд░рдг, ViewPager2 рдХреЗ рд▓рд┐рдП рдПрдбреЗрдкреНрдЯрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewPager2.adapter = ViewPagerAdapter() } }
рд╡рд╣ рд╕рдм рд╣реИ! PagerAdapter рдХреЗ рд╕рд╛рде рдкреБрд░рд╛рдиреЗ ViewPager рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╣рдореЗрдВ рд╡рд╣реА рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ:

рд▓рдВрдмрд╡рдд рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ
рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдКрд░реНрдзреНрд╡рд╛рдзрд░ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рддрдХ, Google рдиреЗ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдЗрд╕ рдирдП ViewPager2 рдореЗрдВ рдЕрдм рд╡рд░реНрдЯрд┐рдХрд▓ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рдкреЛрд░реНрдЯ рд╣реИред рдмрд╕ ViewPager2 рдореЗрдВ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдмрджрд▓реЗрдВ рдФрд░ рдКрд░реНрдзреНрд╡рд╛рдзрд░ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╕рдХреНрд╖рдо рд╣реЛ рдЬрд╛рдПрдЧреАред рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ!
viewPager2.orientation = ViewPager2.ORIENTATION_VERTICAL
рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:

FragmentStateAdapter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдЖрдк рдкреГрд╖реНрдареЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкреБрд░рд╛рдиреЗ рд╡реНрдпреВ рдкреЗрдЬрд░ рдореЗрдВ рднреА рдЯреБрдХрдбрд╝реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ 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")}" } } }
рдЕрдм рд╣рдо ViewPager2 рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдбреЗрдкреНрдЯрд░ рдмрдирд╛рдПрдВрдЧреЗред рд╣рдо FragmentManager рдХреЛ рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рдкрд╛рд╕ рднреЗрдЬреЗрдВрдЧреЗ, рдЬреЛ рдЯреБрдХрдбрд╝реЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░реЗрдЧрд╛:
class ViewPagerFragmentStateAdapter(fm: FragmentManager) : FragmentStateAdapter(fm) { private val 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 }
рдЕрдм ViewPager2 рдореЗрдВ рдЗрд╕ рдирдП рдПрдбреЗрдкреНрдЯрд░ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рдФрд░ рдЖрдк рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
viewPager2.adapter = ViewPagerFragmentStateAdapter(supportFragmentManager)
рдмреЗрд╣рддрд░ OnPageChangeCallback
рдкреБрд░рд╛рдиреЗ ViewPager рдореЗрдВ, OnPageChangeListner рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдкреЗрдЬ рдкрд░рд┐рд╡рд░реНрддрди / рд╕реНрдХреНрд░реЙрд▓ рдИрд╡реЗрдВрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдФрд░ рдпрд╣ рдмрд╣реБрдд рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╕рднреА рддреАрди рддрд░реАрдХреЛрдВ ( onPageScrollStateChanged
, onPageScrolled
, onPageSelected
) рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рднрд▓реЗ рд╣реА рд╣рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗред
oldViewPager.addOnPageChangeListener(object:ViewPager.OnPageChangeListener{ override fun onPageScrollStateChanged(state: Int) {
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ OnPageChangeCallback
, рдПрдХ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЧреИрд░-рдЕрдореВрд░реНрдд рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВред рдЬрд┐рд╕рдХрд╛ рд╢рд╛рдмреНрджрд┐рдХ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЗрди рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╣рдо рдХреЗрд╡рд▓ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреГрд╖реНрда рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position)
рдЪреЗрддрд╛рд╡рдиреА!
рдЪреВрдВрдХрд┐ ViewPager2 рдЕрд▓реНрдлрд╛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреБрд░рд╛рдиреЗ ViewPager рдХреЗ рдХреБрдЫ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рдЕрднреА рддрдХ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВ рдпрд╛ рдЗрд╕ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдареАрдХ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЬреНрдЮрд╛рдд рдореБрджреНрджреЗ:
- ClipToPadding,
- TabLayout рдХреЗ рд╕рд╛рде рдХреЛрдИ рдПрдХреАрдХрд░рдг рдирд╣реАрдВ,
- рд╕реНрдХреНрд░реАрди рдХреЗ рдмрд╛рд╣рд░ рдХреЛрдИ рдирд┐рдпрдВрддреНрд░рдг рдирд╣реАрдВ рд╣реИ,
- рдкреГрд╖реНрда рдХреА рдЪреМрдбрд╝рд╛рдИ рд╕реЗрдЯ рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреА (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ 100%)
рдЬреНрдЮрд╛рдд рдореБрджреНрджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдБ рд╣реИ ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдЕрдЧрд▓реЗ рдЕрдкрдбреЗрдЯ рдореЗрдВ рддрдп рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдореИрдВ рдЗрд╕ рдирдП ViewPager2 рдХреЗ рдПрдХ рд╕реНрдерд┐рд░ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рддрдм рддрдХ, рд╕рднреА рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рдХреЛрдб!