我们需要一个自动滚动视图,它应该在 X 秒后显示下一个项目,并且应该有一个可控的滚动速度。我们为此使用了 ViewPager2,并决定使用与此处找到的解决方案类似的解决方案,该解决方案利用假拖动来控制滚动持续时间:
fun ViewPager2.setCurrentItem(
item: Int,
duration: Long,
interpolator: TimeInterpolator = LinearInterpolator(),
pagePxWidth: Int = width // Default value taken from getWidth() from ViewPager2 view
) {
val pxToDrag: Int = pagePxWidth * (item - currentItem)
val animator = ValueAnimator.ofInt(0, pxToDrag)
var previousValue = 0
animator.addUpdateListener { valueAnimator ->
val currentValue = valueAnimator.animatedValue as Int
val currentPxToDrag = (currentValue - previousValue).toFloat()
fakeDragBy(-currentPxToDrag)
previousValue = currentValue
}
animator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator?) { beginFakeDrag() }
override fun onAnimationEnd(animation: Animator?) { endFakeDrag() }
override fun onAnimationCancel(animation: Animator?) { /* Ignored */ }
override fun onAnimationRepeat(animation: Animator?) { /* Ignored */ }
})
animator.interpolator = interpolator
animator.duration = duration
animator.start()
}
pagePxWidth
我们为此使用的是,width - offsetAndMargin.toInt()
其中width
是 ViewPager2 的宽度,offsetAndMargin
是应用于项目的偏移量和边距的总和。
我们的视图还需要将第一项推到左侧,以便在第一项和屏幕边缘之间几乎没有空白,并且相同的处理也适用于最后一项,并对其应用偏移量但这次它向右偏移。请参阅图表以更好地说明我的意思:
我们已经实现了这一点,使用类似于在此处PageTransformer
找到的解决方案,使用如下:
private fun ViewPager2.setPageTransformer() {
setPageTransformer { page, position ->
var translationX = -offsetAndMargin * position
if (currentItem == 0) {
translationX -= margin
} else if (currentItem == entries.size - 1) {
translationX += margin
}
page.translationX = translationX
}
}
问题在于,使用自动滚动时,它会导致到第二个项目和最后一个项目的抖动/抖动过渡。玩弄pagePxWidth
传递给的值setCurrentItem
没有效果。减少应用于第一个和最后一个项目的偏移量似乎可以解决抖动问题,但我们希望尽可能地坚持我们的原始设计。任何人都有关于如何消除抖动的想法或有任何使用假拖动的经验PageTransformer
?