Migrating from ViewPager to ViewPager2 with FragmentStateAdapter causes visible screen yank and StrictMode to be triggered

I've followed the Android documentation and this tutorial to migrate to ViewPager2. When swiping the 4 screens from left to right, there is a visible screen yank which is not a great user experience. I've used strictmode to measure the performance.

The documentation explicitly mentions that createFragment must provide a new Fragment each time so the implementation seems to be implemented correct.


private fun initializeViewPager(items: List<Item>) {
    val tabAdapter = TabAdapter(this, items)
    viewPager2.adapter = tabAdapter

    TabLayoutMediator(tabLayout, viewPager2) { tab, position ->
        tab.text = items[position].abbreviation

class TabAdapter(activity: AppCompatActivity, private val items: List<Item>) :
    FragmentStateAdapter(activity) {

    override fun getItemCount(): Int {
        return items.size

    override fun getItemId(position: Int): Long {
        return items[position].getId()

    override fun createFragment(position: Int): Fragment {
        return VersesFragment.getInstance(items[position])


class SomeFragment : DaggerFragment()  {

    var adapter: ItemAdapter? = null

    private lateinit var binding: FragmentSomeBinding

    private lateinit var item: Item

    override fun onCreate(savedInstanceState: Bundle?) {


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentSomeBinding.inflate(inflater, container, false).apply {
            lifecycleOwner = viewLifecycleOwner

        return binding.root

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        .. Setting of view elements using the serialized item

    private fun handleArguments() {
        val args = arguments
            ?: throw NullPointerException("getArguments() seems to be null. ARG_BIBLETRANSLATION needed!")

        if (!args.containsKey(ARG_BIBLETRANSLATION)) throw NullPointerException("getArguments() does not contain ARG_BIBLETRANSLATION!")

        item = args[ARG_BIBLETRANSLATION] as Item

    companion object {

        const val ARG_MY_ITEM = "arg_my_item"

        fun getInstance(item: Item): Fragment {

            val fragment = VersesFragment()

            fragment.arguments = Bundle(2).apply {
                putSerializable(ARG_MY_ITEM, item)

            return fragment


<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">


            android:layout_height="match_parent" />


Just for completeness, here is the original code that does perform fine:


val adapter = SomePagerAdapter(items as ArrayList<Item>)
viewPager.adapter = sdapter


class SomePagerAdapter(private val items: ArrayList<Item>) : PagerAdapter() {
    override fun instantiateItem(container: ViewGroup, position: Int): Any { 
        // Same code as in SomeFragment

The tutorial from raywenderlich is super simple, but when enabling strictmode, it does get triggered, while strictmode does not get triggered with the old viewpager and the same code:

  private fun enableStrictMode() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {

Read more here: https://stackoverflow.com/questions/64892174/migrating-from-viewpager-to-viewpager2-with-fragmentstateadapter-causes-visible

Content Attribution

This content was originally published by Jim Clermonts at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: