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

时间:2016-06-01 06:49:24

标签: android android-fragments android-viewpager android-animation android-pagetransformer

我希望显示具有反弹/弹性滑动效果的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

我已经提到了以下帖子:

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

有没有人确切知道我们如何将BounceInterpolatorPageTransformer合并?这个 似乎 是解决这个问题的有机且连贯的方法,但它甚至可能吗?或者还有其他合理的解决方案吗?

参考文献:

N.B:

只需合并InterpolatorPageTransformer即可 可以实现弹性/反弹动画效果,而无需扩展ViewPager 。其他方法也欢迎,但请提供详细的代码解决方案,而不仅仅是大纲。

3 个答案:

答案 0 :(得分:3)

您可以使用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);

答案 1 :(得分:0)

看看this library,也许它可以帮到你。

答案 2 :(得分:0)

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

因此,使用由ValueAnimator触发的标准OnPageChangeListener API会更好。当然,在这种情况下,我们还有另一个警告,但这种做法似乎更有希望。