tommybuonomo / dotsindicator

Three material Dots Indicators for view pagers in Android !

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ViewPager2 version of library crashes when there is only 1 page

ahctangU opened this issue · comments

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)
      }

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

commented

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