What is the best way to achieve an elastic / bounce animation effect in ViewPager?

断了今生、忘了曾经 提交于 2019-12-08 02:45:36

问题


I want to display a ViewPager with a bounce / elastic sliding effect. I suppose that this is possible using some combination of a PageTransformer and a BounceInterpolator.

What I do not know is how. Thus far I have been unable to achieve this.

A typical example of a PageTransformer would be something like this:

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

The question is, how do we bring an Interpolator (of any kind) into the picture here? Where do we get the Animation object for the ViewPager's animation from, so as to set an Interpolator to it?

I have already referred to the following posts:

  • 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.

The third post has an answer that mentions this very approach, but does not provide any detail as to how.

Does anyone know exactly how do we go about combining a BounceInterpolator with a PageTransformer? This seems to be an organic and coherent approach to this problem, but is it even possible at all? Or is there another logical solution for this?

References:

  • Customize the ViewPager with PageTransformer.

N.B:

It should be possible to achieve an elastic / bounce animation effect simply by combining an Interpolator and a PageTransformer, and without having to extend the ViewPager. Other approaches are also welcome, but please provide a detailed solution with code, not just an outline.


回答1:


You can use fakeDragBy method to achieve this effect:

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

Or you can Use this method:

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

In Java Class Use only this :

animateViewPager(pager, 10, 1000);



回答2:


Take a look at this library, maybe it could help you.




回答3:


I'm not sure that PageTransformer is the best way to achieve mentioned effect. Note, that such transformations will be the same in both swiping directions, since received position gives no idea about if we swipe left-to-right or vice versa. And probably you don't want bouncing of two opposite sides of view, but only one, to which pull is applied. And the second, and IMO more important, PageTransformer framing is driven by user's gesture, not by stable system clock. And as result - we can't control duration of fade phase (phase when user has released his/her finger) and achieve smooth behavior (because in general ticks are delivered with non-monotonically changed position, that depends heavily on touch velocity).

So, it would be much better to use standard ValueAnimator API, that will be triggered by OnPageChangeListener. Of course in this case we have another caveats but this approach seems to be more promising.



来源:https://stackoverflow.com/questions/37561357/what-is-the-best-way-to-achieve-an-elastic-bounce-animation-effect-in-viewpage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!