问题
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