androidandroid-viewpagerandroid-viewpager2

Viewpager2 add item at 0th position scrolling issue


After adding an item at the 0th position on Viewpager2, the item does not scroll/add correctly to the view and shows the current view again after scrolling. The main initial item is not visible after adding items to the 0th position.

Sample screen record here

My Viewpager's Adapter looks like the following.

   inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
    override fun getItemCount(): Int {
        return list.size
    }

    override fun createFragment(position: Int): Fragment = ScrollFragment(list[position])

    fun addFragment(string: String) {
        list.add(string)
        notifyItemInserted(list.size)
    }

    fun addAtPreviousFragment(string: String) {
        list.add(0, string)
        notifyItemInserted(0)
    }
}

The addAtPreviousFragment is adding the video to the 0th position.

ViewPager's add item at next, and 0th position looks like following

  mAddAtNext.setOnClickListener {
            Handler(Looper.getMainLooper()).postDelayed(
                {
                    val randomNext = (50..90).random()
                    println("randomNext >>>>>> $randomNext")
                    pagerAdapter.addFragment("Next $randomNext")

                }, 200
            )
        }

        mAddAtPrevious.setOnClickListener {
            Handler(Looper.getMainLooper()).postDelayed(
                {
                    val randomPrevious = (0..40).random()
                    println("randomPrevious >>>>>> $randomPrevious")
                    pagerAdapter.addAtPreviousFragment("Previous $randomPrevious")
                }, 200
            )
        }

Code for the same is added to Git Hub.

Any help is appreciated. Thanks in advance


Solution

  • Tested and working perfectly fine, Use another Mutable-list in the adapter to avoid any uncertainty

    class MainActivity : AppCompatActivity() {
    
    private lateinit var list: ArrayList<String>
    private lateinit var pagerAdapter: ScreenSlidePagerAdapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setUpViewPager()
    }
    
    fun setUpViewPager() {
        list = arrayListOf()
        list.add("45")
        val mViewPager: ViewPager2 = findViewById(R.id.view_pager)
    
        pagerAdapter = ScreenSlidePagerAdapter(this)
        mViewPager.adapter = pagerAdapter
    
        val mAddAtNext: AppCompatButton = findViewById(R.id.btn_next)
        val mAddAtPrevious: AppCompatButton = findViewById(R.id.btn_previous)
    
        pagerAdapter.submitInitialItem(list.first())
        mAddAtNext.setOnClickListener {
            val randomNext = (50..90).random()
            println("randomNext >>>>>> $randomNext")
            pagerAdapter.addFragment("Next $randomNext")
        }
    
        mAddAtPrevious.setOnClickListener {
            val randomPrevious = (0..40).random()
            println("randomPrevious >>>>>> $randomPrevious")
            pagerAdapter.addAtPreviousFragment("Previous $randomPrevious")
        }
    }
    
    inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
        private val fragmentList: MutableList<Fragment> = mutableListOf()
        fun submitInitialItem(string: String) {
            fragmentList.add(ScrollFragment(string))
        }
    
    
        override fun getItemCount(): Int {
            return fragmentList.size
        }
    
        override fun createFragment(position: Int): Fragment = fragmentList[position]
    
        fun addFragment(string: String) {
            fragmentList.add(ScrollFragment(string))
            notifyItemInserted(fragmentList.size)
        }
    
        fun addAtPreviousFragment(string: String) {
            fragmentList.add(0, ScrollFragment(string))
            notifyItemInserted(0)
        }
    
        override fun getItemId(position: Int): Long {
            return fragmentList[position].hashCode().toLong()
        }
    
        override fun containsItem(itemId: Long): Boolean {
            return fragmentList.any { it.hashCode().toLong() == itemId }
        }
    }}
    

    Reference GIF of the above implementation:enter image description here