Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ViewPager2 version of library crashes when there is only 1 page #56

Closed
ahctangU opened this issue Sep 10, 2019 · 2 comments
Closed

ViewPager2 version of library crashes when there is only 1 page #56

ahctangU opened this issue Sep 10, 2019 · 2 comments

Comments

@ahctangU
Copy link

ahctangU commented Sep 10, 2019

Unlike viewpager, for viewpager2, the onPageScrolled handler is called when the view is first rendered. However, the following code snippet assumes there will always be a next page. This causes an index out of range exception crash.

This is happening for v4.1.1

fun onPageScrolled(position: Int, positionOffset: Float) {
    var offset = (position + positionOffset)
    val lastPageIndex = (pageCount - 1).toFloat()
    if (offset == lastPageIndex) {
      offset = lastPageIndex - .0001f
    }
    val leftPosition = offset.toInt()
    val rightPosition = leftPosition + 1 <-- lastPageIndex is taken into account, but right position is still assumed to be left + 1 even when left and right are the same position for a 1 page viewpager
    onPageScrolled(leftPosition, rightPosition, offset % 1)

    if (lastLeftPosition != -1) {
      if (leftPosition > lastLeftPosition) {
        (lastLeftPosition until leftPosition).forEach {
          resetPosition(it)
        }
      }

      if (rightPosition < lastRightPosition) {
        resetPosition(lastRightPosition)
        ((rightPosition + 1)..lastRightPosition).forEach {
          resetPosition(it)
        }
      }
    }

    lastLeftPosition = leftPosition
    lastRightPosition = rightPosition
  }

Specifically the crash happens on this line.

 override fun onPageScrolled(selectedPosition: Int, nextPosition: Int, positionOffset: Float) {
        val x = (dots[selectedPosition].parent as ViewGroup).left.toFloat()
        val nextX = (dots[if (nextPosition == -1) selectedPosition else nextPosition].parent as ViewGroup).left <--- dots[nextPosition] is now left position + 1 which is out of range.
                .toFloat()
        val xFinalPosition: Float
        val widthFinalPosition: Float

        when (positionOffset) {
          in 0.0f..0.1f -> {
            xFinalPosition = x
            widthFinalPosition = dotsSize
          }
          in 0.1f..0.9f -> {
            xFinalPosition = x
            widthFinalPosition = nextX - x + dotsSize
          }
          else -> {
            xFinalPosition = nextX
            widthFinalPosition = dotsSize
          }
        }

        dotIndicatorXSpring?.animateToFinalPosition(xFinalPosition)
        dotIndicatorWidthSpring?.animateToFinalPosition(widthFinalPosition)
      }
@tommybuonomo
Copy link
Owner

Hi @ahctangU ,
Normally, this is fixed in the version 4.1.2. Can you try to confirm please ?

@ahctang
Copy link

ahctang commented Sep 10, 2019

Oh I totally missed that you made a new release. Yes it is fixed in 4.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants