extmkv / CircularViewPager

A circular ViewPager example using the new ViewPager2
8 stars 0 forks source link

How to set current item to nth position? #2

Open objectorientedperson opened 5 years ago

objectorientedperson commented 5 years ago

Hi, let's say you have 20 items and you want to set the current to 16th item. How to do this?

isacab commented 4 years ago

Use setCurrentItem(int item) on ViewPager2 https://developer.android.com/reference/kotlin/androidx/viewpager2/widget/ViewPager2.html#setCurrentItem(kotlin.Int)

objectorientedperson commented 4 years ago

@isacab no actually what I mean is, when you set Integer.MAX_COUNT for adapter, setCurrentItem(int item) the endless/infinite scroll functionality is gone. To be able to get correct index I wrote something:

private fun getFakeCurrent(item: Int): Int {
    val real = mFragmentList.count()
    if (real <= 0) return item

    // Set number probably find an intermediate position
    val index = itemCount / 2 / real

    // Returns first item position intermediate set of
    return index * real + item
  }

So that user can scroll to both sides. setCurrentItem(position: Int) sets the position to beginning. That's the problem.

objectorientedperson commented 4 years ago

So for someone who is in search with this issue, the above code actually works. So along with @extmkv 's code:

class CircularPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {

    override fun getItemCount() = Integer.MAX_VALUE

    /**
     * Create the fragment based on the position
     */
    override fun createFragment(position: Int) = HomePagerScreens.values()[position % HomePagerScreens.values().size].fragment.java.newInstance()

    /**
     * Returns the same id for the same Fragment.
     */
    override fun getItemId(position: Int): Long = (position % HomePagerScreens.values().size).toLong()

    fun getCenterPage(position: Int = 0) = Integer.MAX_VALUE / 2 + position
}

I have added these below:

/**
   * Sets view pager to fake position.
   */
  fun setCurrent(mViewPager2: ViewPager2?, index: Int = 0) {
    mViewPager2?.setCurrentItem(getFakeCurrent(index), false)
  }

  /**
   * Calculates fake current position.
   */
  private fun getFakeCurrent(item: Int): Int {
    val real = mFragmentList.count()
    return when {
      real <= 1 -> item
      else -> {
        val index = itemCount / real / 2
        index * real + item
      }
    }
  }

@isacab's answer sets index to nth position where endless/infinite scroll doesn't work. Also, if I add 'offscreenPageLimit' it basically doesn't render my fragments (shows you blank fragments). So don't forget to remove it.

Cheers.