自动轮播并且能够无限轮播的ViewPager,可纵向滑动、可修改滑动速度

/**
 * 实现自动轮播,无限轮播的viewpager
 * 需要对传入adapter的list做处理:在list的首、尾两个位置分别添加原来list的list.get(getAdapter().getCount()()-1)和list.get(0);
 * 即传入的数据源比实际要展示的多两项;
 * Created by Dovar_66 on 2016/9/30 .
 */
public class AutoViewPager extends ViewPager {
   
private int time = 2500;        //默认跳转间隔2.5秒
private int oldx = 0;           //点击位置的x坐标
private int oldy = 0;           //点击位置的y坐标
private int current = 0;//当前图片

private boolean isTouch = false;        //判断是否点击viewpager
private boolean isLeft = false;             //判断是向左滑还是右滑
private RadioGroup mIndicator;         //页码指示器

private ExecutorService mExecutorService = Executors.newCachedThreadPool();//创建一个可缓存线程池
private int count = 0;//每次页面跳转时计数+1
private final ThreadLocal<Integer> selectcount = new ThreadLocal<Integer>() {
    @Override
    protected Integer initialValue() {
        return 0;
    }
};


public AutoViewPager(Context context) {
    this(context, null);
}

public AutoViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.setOnPageChangeListener(changeListener);
}

/**
 * 设置自动滑动的间隔时间
 *
 * @param time 时间
 */
public void setTime(int time) {
    this.time = time;
}

/**
 * 开启自动滑动
 */
public void startTurn() {
    if (getAdapter().getCount() == 0) {
        return;
    }
    setCurrentItem(1);
}

/**
 * 设置页码指示器
 *
 * @param mRadioGroup
 */
public void setIndicator(RadioGroup mRadioGroup) {
    mIndicator = mRadioGroup;
}

/**
 * 修改滑动速度
 */
public void setSpeed(int duration) {
    try {
        Field mScroller = ViewPager.class.getDeclaredField("mScroller");
        mScroller.setAccessible(true);
        FixedSpeedScroller scroller = new FixedSpeedScroller(getContext(), new AccelerateInterpolator());
        scroller.setDuration(duration);
        mScroller.set(this, scroller);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    oldx = (int) event.getX();
    oldy = (int) event.getY();
    int mMoveX = 0;
    isTouch = true;
    //当按下时,正好显示的是最后一页,设置当前页为第二页
    //当按下时,正好显示的是第一页,设置当前页为倒数第二页
    if (current == getAdapter().getCount() - 1) {
        current = 1;
        this.setCurrentItem(current, false);
    } else if (current == 0) {
        current = getAdapter().getCount() - 2;
        this.setCurrentItem(current, false);
    }
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        mMoveX = (int) event.getX();
        //判断向左滑还是向右滑
        isLeft = mMoveX - event.getX() < 0;
        //手指在x轴方向上的位移小于y轴方向上位移时,不处理此次touch事件
        if (Math.abs(oldx - event.getX()) - Math.abs(oldy - event.getY()) < 0) return false;
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        isTouch = false;
    }
    return super.onTouchEvent(event);
}

Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (current == getAdapter().getCount() - 1) {
            tailToHead();
        } else {
            current++;
            setCurrentItem(current);
        }
    }
};

OnPageChangeListener changeListener = new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(final int position, final float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        if (mIndicator != null) {
            int pos;
            if (position == 0) {
                pos = getAdapter().getCount() - 3;
            } else if (position == getAdapter().getCount() - 1) {
                pos = 0;
            } else {
                pos = position - 1;
            }
            RadioButton btn = (RadioButton) mIndicator.getChildAt(pos);
            mIndicator.clearCheck();
            mIndicator.check(btn.getId());
        }

        count++;
        mExecutorService.execute(new Runnable() {
            @Override
            public void run() {
                selectcount.set(count);
                try {
                    Thread.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (selectcount.get() == count && !isTouch) {
                    //线程沉睡期间页面未发生跳转并且viewpager当前不处于触摸状态则发送消息,否则不发送此条消息
                    mHandler.sendEmptyMessage(0);
                } else if (selectcount.get() == count && isTouch) {
                    //页面未发生跳转但viewpager当前处于触摸状态,不发送此条消息,准备下一条计时消息
                    mExecutorService.execute(this);
                }
            }
        });

        if (position != getAdapter().getCount()) {
            current = position;
        }
        int pageIndex = position;

        if (position == getAdapter().getCount() - 1 && isTouch) {
            if (!isLeft) {
                tailToHead();
            }
            pageIndex = 1;
        } else if (position == 0 && isTouch) {
            if (isLeft) {
                headToTail();
            }
            pageIndex = getAdapter().getCount() - 2;
        }

        if (position != pageIndex) {
            setCurrentItem(pageIndex, true);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
};
/**
 * 最后一页转至第二页
 */
private void tailToHead() {
    current = 1;//最后一页与第二页的内容相同,第一页与倒数第二页的内容相同
    this.setCurrentItem(current, false);
    current++;
    this.setCurrentItem(current, true);
}

/**
 * 第一页转至倒数第二页
 */
private void headToTail() {
    current = getAdapter().getCount() - 1;
    this.setCurrentItem(current, false);
    current--;
    this.setCurrentItem(current, true);

}

}

详细看demo,已上传github:点击打开链接

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值