在 ViewPager 中实现弹性/反弹动画效果的最佳方法是啥?

Posted

技术标签:

【中文标题】在 ViewPager 中实现弹性/反弹动画效果的最佳方法是啥?【英文标题】:What is the best way to achieve an elastic / bounce animation effect in ViewPager?在 ViewPager 中实现弹性/反弹动画效果的最佳方法是什么? 【发布时间】:2016-09-30 09:22:09 【问题描述】:

我想显示一个具有弹跳/弹性滑动效果的ViewPager。我想这可以使用PageTransformerBounceInterpolator 的某种组合来实现。

我不知道的是如何。到目前为止,我一直无法做到这一点。

PageTransformer 的典型示例如下所示:

public class TypicalPageTransformer implements ViewPager.PageTransformer 

    @Override
    public void transformPage(View view, float position) 

        if (position < -1)  // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

         else if (position <= 0)  // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);

         else if (position <= 1)  // (0,1]
            // Fade the page out.
            view.setAlpha(1 - position);

            // Counteract the default slide transition
            view.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

         else  // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        
    

问题是,我们如何将Interpolator(任何类型的)带入这里的图片中? 我们从哪里得到ViewPager的动画的Animation对象,以便为它设置一个Interpolator

我已经参考了以下帖子:

android VIewpager How to achieve the bound effect.

How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

Add “Rubber Band” effect in android while changing background of application.

第三篇文章的答案提到了这种方法,但没有提供任何细节。

有谁知道我们如何将BounceInterpolatorPageTransformer 结合起来?这似乎是解决这个问题的有机和连贯的方法,但它甚至可能吗?还是有其他合乎逻辑的解决方案?

参考资料:

Customize the ViewPager with PageTransformer

注意:

应该可以简单地通过组合InterpolatorPageTransformer 来实现弹性/反弹动画效果,而无需扩展ViewPager。也欢迎其他方法,但请提供带有代码的详细解决方案,而不仅仅是大纲。

【问题讨论】:

这个例子会成立吗? github.com/chenupt/SpringIndicator 自定义 viewpager 并在 ontTouchEvent 中使用一组按顺序播放的 ValueAnimators 缩放列表视图。 【参考方案1】:

你可以使用 fakeDragBy 方法来实现这个效果:

 viewPager.beginFakeDrag();
viewPager.fakeDragBy(offset); //offset in pixels. 
viewPager.endFakeDrag();

或者你可以使用这个方法:

private int animFactor;
private ValueAnimator animator = new ValueAnimator();

private void animateViewPager(final ViewPager pager, final int offset, final int delay) 
    if (!animator.isRunning()) 
        animator.removeAllUpdateListeners();
        animator.removeAllListeners();
        //Set animation
        animator.setIntValues(0, -offset);
        animator.setDuration(delay);
        animator.setRepeatCount(1);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
            public void onAnimationUpdate(ValueAnimator animation) 
                Integer value = animFactor * (Integer) animation.getAnimatedValue();
                if (!pager.isFakeDragging()) 
                    pager.beginFakeDrag();
                
                pager.fakeDragBy(value);
            
        );
        animator.addListener(new AnimatorListenerAdapter() 

            @Override
            public void onAnimationStart(Animator animation) 
                animFactor = 1;
            

            @Override
            public void onAnimationEnd(Animator animation) 
                pager.endFakeDrag();
            

            @Override
            public void onAnimationRepeat(Animator animation) 
                animFactor = -1;
            
        );
        animator.start();
    

在 Java 类中只使用这个:

animateViewPager(pager, 10, 1000);

【讨论】:

【参考方案2】:

看看this library,也许对你有帮助。

【讨论】:

【参考方案3】:

我不确定PageTransformer 是实现上述效果的最佳方式。请注意,这样的转换在两个滑动方向上都是相同的,因为接收到的位置不知道我们是否从左到右滑动,反之亦然。并且您可能不希望视图的两个相对侧面弹跳,而只希望其中一个应用拉力。第二个,更重要的是 IMO,PageTransformer 框架由用户的手势驱动,而不是由稳定的系统时钟驱动。结果 - 我们无法控制淡入淡出阶段(用户松开手指的阶段)的持续时间并实现平滑的行为(因为通常滴答声以非单调变化的位置传递,这在很大程度上取决于触摸速度)。

所以,最好使用标准的ValueAnimator API,它会由OnPageChangeListener 触发。当然,在这种情况下,我们还有其他注意事项,但这种方法似乎更有希望。

【讨论】:

感谢您理解这个问题... :)

以上是关于在 ViewPager 中实现弹性/反弹动画效果的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Android中实现ProgressBar菊花旋转的动画效果

在VUE中实现动画效果 订单收纳 购物车收纳

怎样在留言板中实现动画效果

Three.js手把手教你在三维场景中实现人物行走动画效果

在 iOS 中实现 AnticipateOvershootInterpolator 动画

JavaScript开关中的幻灯片动画不一致