以编程方式滑动时更改ViewPager动画持续时间
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以编程方式滑动时更改ViewPager动画持续时间相关的知识,希望对你有一定的参考价值。
我正在改变幻灯片
viewPager.setCurrentItem(index++, true);
但它变快了。有没有办法手动设置动画速度?
答案
我想做自己并且已经实现了解决方案(但是使用反射)。
我还没有测试它,但它应该工作或需要最小的修改。
在Galaxy Nexus JB 4.2.1上测试。你需要在XML而不是ViewPagerCustomDuration
中使用ViewPager
,然后你可以这样做:
ViewPagerCustomDuration vp = (ViewPagerCustomDuration) findViewById(R.id.myPager);
vp.setScrollDurationFactor(2); // make the animation twice as slow
ViewPagerCustomDuration.java
:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.animation.Interpolator;
import java.lang.reflect.Field;
public class ViewPagerCustomDuration extends ViewPager
public ViewPagerCustomDuration(Context context)
super(context);
postInitViewPager();
public ViewPagerCustomDuration(Context context, AttributeSet attrs)
super(context, attrs);
postInitViewPager();
private ScrollerCustomDuration mScroller = null;
/**
* Override the Scroller instance with our own class so we can change the
* duration
*/
private void postInitViewPager()
try
Field scroller = ViewPager.class.getDeclaredField("mScroller");
scroller.setAccessible(true);
Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
mScroller = new ScrollerCustomDuration(getContext(),
(Interpolator) interpolator.get(null));
scroller.set(this, mScroller);
catch (Exception e)
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor)
mScroller.setScrollDurationFactor(scrollFactor);
ScrollerCustomDuration.java
:
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;
public class ScrollerCustomDuration extends Scroller
private double mScrollFactor = 1;
public ScrollerCustomDuration(Context context)
super(context);
public ScrollerCustomDuration(Context context, Interpolator interpolator)
super(context, interpolator);
@SuppressLint("NewApi")
public ScrollerCustomDuration(Context context, Interpolator interpolator, boolean flywheel)
super(context, interpolator, flywheel);
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor)
mScrollFactor = scrollFactor;
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration)
super.startScroll(startX, startY, dx, dy, (int) (duration * mScrollFactor));
希望这有助于某人!
另一答案
基于@df778899's answer和Android ValueAnimator API,我找到了更好的解决方案。没有反射它工作正常,非常灵活。此外,无需自定义ViewPager并将其放入android.support.v4.view包中。这是一个例子:
private void animatePagerTransition(final boolean forward)
ValueAnimator animator = ValueAnimator.ofInt(0, viewPager.getWidth());
animator.addListener(new Animator.AnimatorListener()
@Override
public void onAnimationStart(Animator animation)
@Override
public void onAnimationEnd(Animator animation)
viewPager.endFakeDrag();
@Override
public void onAnimationCancel(Animator animation)
viewPager.endFakeDrag();
@Override
public void onAnimationRepeat(Animator animation)
);
animator.setInterpolator(new AccelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
private int oldDragPosition = 0;
@Override
public void onAnimationUpdate(ValueAnimator animation)
int dragPosition = (Integer) animation.getAnimatedValue();
int dragOffset = dragPosition - oldDragPosition;
oldDragPosition = dragPosition;
viewPager.fakeDragBy(dragOffset * (forward ? -1 : 1));
);
animator.setDuration(AppConstants.PAGER_TRANSITION_DURATION_MS);
if (viewPager.beginFakeDrag())
animator.start();
更新:
只是检查是否可以使用此解决方案一次刷几页(例如,如果第一页应显示在最后一页之后)。这是稍加修改的代码,用于处理指定的页数:
private int oldDragPosition = 0;
private void animatePagerTransition(final boolean forward, int pageCount)
// if previous animation have not finished we can get exception
if (pagerAnimation != null)
pagerAnimation.cancel();
pagerAnimation = getPagerTransitionAnimation(forward, pageCount);
if (viewPager.beginFakeDrag()) // checking that started drag correctly
pagerAnimation.start();
private Animator getPagerTransitionAnimation(final boolean forward, int pageCount)
ValueAnimator animator = ValueAnimator.ofInt(0, viewPager.getWidth() - 1);
animator.addListener(new Animator.AnimatorListener()
@Override
public void onAnimationStart(Animator animation)
@Override
public void onAnimationEnd(Animator animation)
viewPager.endFakeDrag();
@Override
public void onAnimationCancel(Animator animation)
viewPager.endFakeDrag();
@Override
public void onAnimationRepeat(Animator animation)
viewPager.endFakeDrag();
oldDragPosition = 0;
viewPager.beginFakeDrag();
);
animator.setInterpolator(new AccelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
@Override
public void onAnimationUpdate(ValueAnimator animation)
int dragPosition = (Integer) animation.getAnimatedValue();
int dragOffset = dragPosition - oldDragPosition;
oldDragPosition = dragPosition;
viewPager.fakeDragBy(dragOffset * (forward ? -1 : 1));
);
animator.setDuration(AppConstants.PAGER_TRANSITION_DURATION_MS / pageCount); // remove divider if you want to make each transition have the same speed as single page transition
animator.setRepeatCount(pageCount);
return animator;
另一答案
public class PresentationViewPager extends ViewPager
public static final int DEFAULT_SCROLL_DURATION = 250;
public static final int PRESENTATION_MODE_SCROLL_DURATION = 1000;
public PresentationViewPager (Context context)
super(context);
public PresentationViewPager (Context context, AttributeSet attrs)
super(context, attrs);
public void setDurationScroll(int millis)
try
Class<?> viewpager = ViewPager.class;
Field scroller = viewpager.getDeclaredField("mScroller");
scroller.setAccessible(true);
scroller.set(this, new OwnScroller(getContext(), millis));
catch (Exception e)
e.printStackTrace();
public class OwnScroller extends Scroller
private int durationScrollMillis = 1;
public OwnScroller(Context context, int durationScroll)
super(context, new DecelerateInterpolator());
this.durationScrollMillis = durationScroll;
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration)
super.startScroll(startX, startY, dx, dy, durationScrollMillis);
如何通过在 ViewPager 中用手指滑动来禁用分页但仍然能够以编程方式滑动?