How to work with ViewPager2

Original author: Birju Vachhani
  • Transfer

How to work with ViewPager2


Not much time has passed since February 7, 2019 Google released the alpha version of Android ViewPager2 . More information about this release can be found here . Now let's see what ViewPager2 is all about.


New features


  • Support layout from right to left,
  • Support vertical orientation,
  • Superior PageChangeListener.

What changed?



ViewPager2 is released for Android X, so if you want to use it, your project should use Android X. Let's see how we can use this new ViewPager2.


Add dependency


Add the following dependency to the file build.gradleat the application level:


dependencies {
    implementation "androidx.viewpager2:viewpager2:1.0.0-alpha01"
}

After that, synchronize your project.


Customization


Add a widget ViewPager2to your Activity or fragment:



Let's create a layout for the page that will be displayed in ViewPager2:


item_page.xml



Next we need to create an Adapter for ViewPager2. This is the most interesting. For this we can use RecyclerView.Adapter. Isn't that cool?


ViewPagerAdapter.kt


class ViewPagerAdapter : RecyclerView.Adapter() {
    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)

This is the same adapter that we use for a regular RecyclerView, and it works just as well with ViewPager2.


Last step, install the adapter for ViewPager2:


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewPager2.adapter = ViewPagerAdapter()
    }
}

That's all! We get the same result as when using the old ViewPager with the PagerAdapter:


Horizontal ViewPager2


Vertical scrolling


Previously, you had to use third-party libraries to implement vertical scrolling, because so far, Google has not provided such an opportunity out of the box. This new ViewPager2 now has support for vertical scrolling. Just change the orientation in ViewPager2 and vertical scrolling will be enabled. Very simple!


viewPager2.orientation = ViewPager2.ORIENTATION_VERTICAL

Here is the result:


Vertical ViewPager2


Using FragmentStateAdapter


You can also use fragments as pages, as in the old ViewPager. There is a FragmentStateAdapter for this. Let's see how we can use it.


First of all, we need to create a fragment:


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

Now we will create an adapter for ViewPager2. We will pass the FragmentManager to its constructor, which will manage the fragments:


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
}

Now install this new adapter in ViewPager2, and you're done:


viewPager2.adapter = ViewPagerFragmentStateAdapter(supportFragmentManager)

Improved OnPageChangeCallback


In the old ViewPager, the interface OnPageChangeListnerwas designed to receive page change / scroll events. And it was very inconvenient, because we needed to override all three methods ( onPageScrollStateChanged, onPageScrolled, onPageSelected), even if we do not want.


oldViewPager.addOnPageChangeListener(object:ViewPager.OnPageChangeListener{
    override fun onPageScrollStateChanged(state: Int) {
        // бесполезный метод
    }
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        // тоже бесполезный
    }
    override fun onPageSelected(position: Int) {
        // метод, который нам нужен
    }
})

Now we have an OnPageChangeCallbackabstract class with non-abstract methods. Which literally means that we don’t need to redefine all these methods, we can simply redefine the ones that we need or that we want to use. So, for example, we can track page change events:


viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        // Теперь только необходимое
    }
})

Attention!


Since ViewPager2 is in the alpha version, there are some functions of the old ViewPager that have not yet been implemented or do not work properly in this version.


Known issues as per documentation:


  • ClipToPadding,
  • No integration with TabLayout,
  • There is no control outside the screen,
  • Cannot set page width (100% by default)

More information about known issues is here . I hope that all this will be fixed in the next updates. I look forward to a stable version of this new ViewPager2. Until then, good code to everyone!


Also popular now: