定制ViewPager——切换效果、滑动速度、全自动轮播

这篇博文是对viewpager自定义时一些零零散散的归纳,目的是能最方便地实现app中常见的banner广告。

---------------- 割 割 割-----------------

定制1:带有纵深的切换效果

方法:通过自定义PageTransformer,实现transformPage(View page, float position)方法。

PageTransformer depthTransformer = new PageTransformer() {
        @Override
        public void transformPage(View page, float position) {
            int pageWidth = page.getWidth();
            if (position < -1) { // [-Infinity,-1)
                page.setAlpha(0);
            } else if (position <= 0) { // [-1,0]
                // Use the default slide transition when moving to the left page
                page.setAlpha(1);
                page.setTranslationX(0);
                page.setScaleX(1);
                page.setScaleY(1);
            } else if (position <= 1) { // (0,1]
                // Fade the page out.
                page.setAlpha(1 - position);
                // Counteract the default slide transition
                page.setTranslationX(pageWidth * -position);
                // Scale the page down (between MIN_SCALE and 1)
                float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
                page.setScaleX(scaleFactor);
                page.setScaleY(scaleFactor);
            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                page.setAlpha(0);
            }
        }
    };

viewpager.setPageTransformer(true, depthTransformer);

定制2:全自动轮播

方法:利用Handler.postDelay()方法,轮询调用Runnable自身

    int maxCount = 0;
    @Override
    public void setAdapter(PagerAdapter adapter) {
        super.setAdapter(adapter);
        maxCount = getAdapter().getCount();
        if (maxCount > 0 && AUTO_ANIM) {
            mHandler.postDelayed(autoRun, DURATION);
        }
    }

    Runnable autoRun = new Runnable() {
        @Override
        public void run() {
            try {
                mHandler.postDelayed(this, DURATION);
                int nextPosition = getCurrentItem() + 1;
                setCurrentItem(nextPosition % maxCount);
            } catch (Exception e) {
            }
        }
    };

定制3:控制切换动画的速度

setCurrentItem执行时会有一个切换的效果,时长很短,一闪而过,我们需要适当的延长切换动画。

另外当item横跨区间超过2个时,切换效果很糟糕,我们需要屏蔽切换动画。

上面的这两个需求,都可以通过自定义Scroller来实现。

public class MScroller extends Scroller {
    private int mScrollDuration = 1000; //切换动画时长
    private static final Interpolator sInterpolator = new Interpolator() {
        @Override
        public float getInterpolation(float t) {
            t -= 1.0f;
            return t * t * t * t * t + 1.0f;
        }
    };
    public boolean noDuration;
    public void setNoDuration(boolean noDuration) {
        this.noDuration = noDuration;
    }
    public MScroller(Context context) {
        this(context, sInterpolator);
    }
    public MScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }
    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        if (noDuration) {
            //不需要时间间隔
            super.startScroll(startX, startY, dx, dy, 0);
        } else {
            super.startScroll(startX, startY, dx, dy, mScrollDuration);
        }
    }
}

然后在自定义vp初始化时通过反射设置vp的mScroller为自定义Scroller

private void init() {
        scroller = new MScroller(getContext());
        Class<ViewPager> cl = ViewPager.class;
        try {
            Field field = cl.getDeclaredField("mScroller");
            field.setAccessible(true);
            //利用反射设置mScroller域为自己定义的MScroller
            field.set(this, scroller);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

设置跨度超过1个禁止动画的规则,重写setCurrentItem

@Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        if (Math.abs(getCurrentItem() - item) > 1) {
            scroller.setNoDuration(true);
            super.setCurrentItem(item, smoothScroll);
            scroller.setNoDuration(false);
        } else {
            scroller.setNoDuration(false);
            super.setCurrentItem(item, smoothScroll);
        }
    }

完工!看下效果:







阅读更多
个人分类: Android开发随笔
上一篇Sonatype Nexus在Maven Central Repository开户实践笔记
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭