ViewPager2
in Android allows the user to flip left and right through pages of data. In our android ViewPager2 application we’ll implement a ViewPager2
that swipes through four views with different background colors and texts.
Following are the features that ViewPager2 brings to us
We can also perform DiffUtil operations on our data to dynamically update the content within our View Pager, this means we don’t need to reload and set the entire data set — only the data that has changed.
What has been changed!
This version of ViewPager2 is released for Android X so if you want to use it then your project must have been migrated to Android X. Let’s see how we can use this new ViewPager2.
Developers familiar with the RecyclerView
will have no trouble adopting the new ViewPager2
APIs. While the ViewPager2
extends from a ViewGroup
, it carriers a RecyclerView under the hood. To provide data to the view, find the ViewPager2
in your layout and set the adapter.
Add following dependency to your app level build.gradle file:
dependencies { implementation "androidx.viewpager2:viewpager2:1.0.0-beta02" }
Add ViewPager2
widget to your Activity/Fragment.
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent"/>
Let’s create a layout for our page representation. Following is a content for 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"> <TextView 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>
Next, we need to create Adapter
for ViewPager2
. For this we can use RecyclerView.Adapter
. Following is a content for ViewPagerAdapter.kt
class ViewPagerAdapter : RecyclerView.Adapter<ViewPagerAdapter.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 ) inner class PagerVH(itemView: View) : RecyclerView.ViewHolder(itemView) { } 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]) } }
Finally, set adapter for ViewPager2
.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewPager2.adapter = ViewPagerAdapter() } }
Vertical Scrolling
With this new ViewPager2
, we have in house support for vertical scrolling. Just set orientation to ViewPager2
and vertical scrolling will be enabled for you!
viewPager2.orientation = ViewPager2.ORIENTATION_VERTICAL
Using FragmentStateAdapter
You can use fragments too as you would with the old ViewPager
. For that, we have FragmentStateAdapter
. Let’s see how we can use this. 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’ll create Adapter for ViewPager2
. It will take FragmentManager
as constructor argument to manage 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 }
That’s it! set this new adapter to viewPage2
and you’re good to go.
viewPager2.adapter = ViewPagerFragmentStateAdapter(supportFragmentManager)
Page Change Callback
You can register a page change callback (in the form of the OnPageChangeCallback
class) on our ViewPager2
. This will allow you to listen for changes on the selected page. Within this callback we can listen for:
onPageScrolled()
— Triggered when a scroll event occurs for the current pageonPageSelected()
— Triggered when a new page becomes selectedonPageScrollStateChanged()
— Triggered when the scroll state changesOnPageChangeCallback
abstract class means that we don’t need to override all these methods, we can just override the ones we care or we willing to use.
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) Log.d(TAG, "onPageSelected") } })
Other
Scroll to page programatically viewPager2.currentItem = PAGE
or viewPager2.setCurrentItem(position, true)
(with Animation).
Disable user scroll: viewPager2.isUserInputEnabled = false
.
You can link TabLayout
and viewPager2
as described here.