为了账号安全,请及时绑定邮箱和手机立即绑定

在Android中Viewpager控制器的速度减慢

/ 猿问

在Android中Viewpager控制器的速度减慢

幕布斯7119047 2019-08-24 16:51:02

在Android中Viewpager控制器的速度减慢

用android中的viewpager适配器有没有办法减慢滚动速度?


你知道,我一直在看这段代码。我无法弄清楚我错了什么。

try{ 
    Field mScroller = mPager.getClass().getDeclaredField("mScroller"); 
    mScroller.setAccessible(true); 
    Scroller scroll = new Scroller(cxt);
    Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
    scrollDuration.setAccessible(true);
    scrollDuration.set(scroll, 1000);
    mScroller.set(mPager, scroll);}catch (Exception e){
    Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();}

它没有改变什么,但没有例外发生?


查看完整描述

3 回答

?
天天世纪

我已经开始使用HighFlyer的代码确实改变了mScroller字段(这是一个很好的开始)但是没有帮助延长滚动的持续时间,因为ViewPager在请求滚动时显式地将持续时间传递给mScroller。

扩展ViewPager不起作用,因为重要的方法(smoothScrollTo)无法被覆盖。

我最后通过使用以下代码扩展Scroller来解决这个问题:

public class FixedSpeedScroller extends Scroller {

    private int mDuration = 5000;

    public FixedSpeedScroller(Context context) {
        super(context);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }


    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }}

并使用它像这样:

try {
    Field mScroller;
    mScroller = ViewPager.class.getDeclaredField("mScroller");
    mScroller.setAccessible(true); 
    FixedSpeedScroller scroller = new FixedSpeedScroller(mPager.getContext(), sInterpolator);
    // scroller.setFixedDuration(5000);
    mScroller.set(mPager, scroller);} catch (NoSuchFieldException e) {} catch (IllegalArgumentException e) {} catch (IllegalAccessException e) {}

我基本上将持续时间硬编码为5秒,并使我的ViewPager使用它。

希望这可以帮助。


查看完整回答
反对 回复 2019-08-24
?
偶然的你

基于已接受的解决方案,我创建了kotlin类,其中包含视图寻呼机的扩展。请享用!:)

class ViewPageScroller : Scroller {

    var fixedDuration = 1500 //time to scroll in milliseconds

    constructor(context: Context) : super(context)

    constructor(context: Context, interpolator: Interpolator) : super(context, interpolator)

    constructor(context: Context, interpolator: Interpolator, flywheel: Boolean) : super(context, interpolator, flywheel)


    override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, fixedDuration)
    }

    override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, fixedDuration)
    }}fun ViewPager.setViewPageScroller(viewPageScroller: ViewPageScroller) {
    try {
        val mScroller: Field = ViewPager::class.java.getDeclaredField("mScroller")
        mScroller.isAccessible = true
        mScroller.set(this, viewPageScroller)
    } catch (e: NoSuchFieldException) {
    } catch (e: IllegalArgumentException) {
    } catch (e: IllegalAccessException) {
    }}


查看完整回答
反对 回复 2019-08-24
?
Cats萌萌
    binding.vpTour.beginFakeDrag();
                lastFakeDrag = 0;
                ValueAnimator va = ValueAnimator.ofInt(0, binding.vpTour.getWidth());
                va.setDuration(1000);
                va.addUpdateListener(animation -> {
                    if (binding.vpTour.isFakeDragging()) {
                        int animProgress = (Integer) animation.getAnimatedValue();
                        binding.vpTour.fakeDragBy(lastFakeDrag - animProgress);
                        lastFakeDrag = animProgress;
                    }
                });
                va.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        if (binding.vpTour.isFakeDragging()) {
                            binding.vpTour.endFakeDrag();
                        }
                    }
                });
                va.start();

我想解决与你们所有人相同的问题,这是我对同一问题的解决方案,但我认为这种解决方案更灵活,因为你可以根据需要更改持续时间,并根据需要更改值的插值实现不同的视觉效果。我的解决方案从页面“1”滑动到页面“2”,因此只能在增加位置,但可以通过执行“animProgress - lastFakeDrag”而不是“lastFakeDrag - animProgress”轻松更改为减少位置。我认为这是执行此任务的最灵活的解决方案。


查看完整回答
反对 回复 2019-08-24

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信