我知道有办法更改ViewPager程序化幻灯片(here)的动画持续时间。

但它不适用于ViewPager2
我尝试了这个:

try {
        final Field scrollerField = ViewPager2.class.getDeclaredField("mScroller");
        scrollerField.setAccessible(true);
        final ResizeViewPagerScroller scroller = new ResizeViewPagerScroller(getContext());
        scrollerField.set(mViewPager, scroller);
    } catch (Exception e) {
        e.printStackTrace();
    }

IDE在“mScroller”上警告我:



如果我们运行此代码,那将无法正常工作,并给我们以下错误:
No field mScroller in class Landroidx/viewpager2/widget/ViewPager2; (declaration of 'androidx.viewpager2.widget.ViewPager2' appears in /data/app/{packagename}-RWJhF9Gydojax8zFyFwFXg==/base.apk)

那么,我们如何才能实现这一功能呢?

最佳答案

基于this issue ticket,Android团队不打算为ViewPager2支持这种行为,请从故障单中建议使用ViewPager2.fakeDragBy()。此方法的缺点是您必须提供页面宽度(以像素为单位),尽管如果页面宽度与ViewPager的宽度相同,则可以使用该值来代替。

这是示例实现

fun ViewPager2.setCurrentItem(
    item: Int,
    duration: Long,
    interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(),
    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()
}

为了支持RTL,您必须翻转提供给ViewPager2.fakeDragBy()的值,因此在上面的示例中,当使用fakeDragBy(-currentPxToDrag)时,请使用fakeDragBy(currentPxToDrag)而不是RTL

基于official docs,在使用此功能时要记住的几点:
  • 负值向前滚动,正向后滚动(使用RTL翻转)
  • 在调用fakeDragBy()之前使用beginFakeDrag(),并在完成endFakeDrag()之后
  • 此API可以轻松地与onPageScrollStateChanged中的ViewPager2.OnPageChangeCallback一起使用,在这里您可以通过isFakeDragging()方法
  • 来区分编程拖动和用户拖动
    如果指定的项目正确,则上面的
  • 示例实现没有安全检查。还可以考虑为UI的生命周期添加取消功能,这可以通过RxJava轻松实现。
  • 关于android - 以编程方式滑动时更改ViewPager2滚动速度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57505875/

    10-10 18:43