效果图:
用法:
viewPager = (ViewPager) getView().findViewById(R.id.viewPager);
viewPager.setAdapter(new BannerAdapter());
indicator = (ViewPagerIndicator) getView().findViewById(R.id.indicator);
indicator.attachViewPager(viewPager);
轮播间隔可在xml中设置(interval_time属性)
也可在jav代码中设置:
indicator.setIntervalTime(4000);
代码:
public class ViewPagerIndicator extends View implements ViewPager.OnPageChangeListener, View.OnTouchListener {
private final String TAG = getClass().getSimpleName();
/**
* 绑定的ViewPager
*/
private ViewPager mViewPager;
/**
* 每一页的间隔时间
*/
private int intervalTime;
/**
* 圆点个数
*/
private int mSize;
/**
* 圆点半径(控件高度的一半)
*/
private int mDotRadius;
/**
* 两个圆水平距离
*/
private int mHorizontalSpacing;
/**
* 两个圆心水平距离
*/
private int mDistanceOfDot;
/**
* pager 滑动偏移量
*/
private float positionOffset;
/**
* 当前pager
*/
private int position;
private Paint mPaint;
/**
* 圆点基础色
*/
private int mBaseColor;
/**
* 当前圆点颜色
*/
private int mCurrentColor;
/**
* 是否需要轮播
*/
private boolean mNeedLoop;
/**
* 和一个ViewPager 绑定
*/
public void attachViewPager(ViewPager mViewPager) {
if (mViewPager == null) return;
this.mViewPager = mViewPager;
mViewPager.addOnPageChangeListener(this);
mSize = mViewPager.getAdapter().getCount();
if (mSize > 1) {
invalidate();
if (mNeedLoop) {
mViewPager.setOnTouchListener(this);
needSwitchPage = true;
postDelayed(nextPage, intervalTime);
}
}
}
/**
* 设置每次轮播间隔
*/
public void setIntervalTime(int intervalTime) {
this.intervalTime = intervalTime;
}
public ViewPagerIndicator(Context context) {
super(context);
init(null);
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
intervalTime = ta.getInt(R.styleable.ViewPagerIndicator_interval_time, 2000);
mBaseColor = ta.getColor(R.styleable.ViewPagerIndicator_base_color, Color.parseColor("#90D3C1B3"));
mCurrentColor = ta.getColor(R.styleable.ViewPagerIndicator_selected_color, Color.WHITE);
mNeedLoop = ta.getBoolean(R.styleable.ViewPagerIndicator_need_loop, true);
ta.recycle();
mPaint = new Paint();
mPaint.setAntiAlias(true);
nextPage = new NextPageRunnable();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSize <= 1) return;
//画基础圆点
int firstDotLeft = ((getWidth() - mSize * 2 * mDotRadius - mHorizontalSpacing * (mSize - 1)) / 2);
int startX = firstDotLeft;
mPaint.setColor(mBaseColor);
for (int i = 0; i < mSize; i++) {
canvas.drawCircle(startX + mDotRadius, getHeight() / 2, mDotRadius, mPaint);
startX += mDistanceOfDot;
}
//画选中的圆点
mPaint.setColor(mCurrentColor);
canvas.drawCircle(firstDotLeft + mDotRadius + (int) (mDistanceOfDot * positionOffset) + position
* mDistanceOfDot, getHeight() / 2, mDotRadius, mPaint);
Log.d(TAG, "onDraw");
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
this.positionOffset = positionOffset;
this.position = position;
invalidate();
}
@Override
public void onPageSelected(int position) {
Log.d(TAG, "onPageScrolled " + position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
private NextPageRunnable nextPage;
private boolean needSwitchPage;
@Override
public boolean onTouch(View v, MotionEvent event) {
removeCallbacks(nextPage);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://接收触摸事件时停止轮播
needSwitchPage = false;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP://手指松开时继续轮播
needSwitchPage = true;
postDelayed(nextPage, intervalTime);
break;
}
return false;
}
/**
* 下一页
*/
private class NextPageRunnable implements Runnable {
@Override
public void run() {
if (!needSwitchPage || getVisibility() != VISIBLE || mViewPager == null || !mNeedLoop)
return;
int currentItem = mViewPager.getCurrentItem();
if (currentItem < mViewPager.getAdapter().getCount() - 1) {
currentItem++;
} else {
currentItem = 0;
}
mViewPager.setCurrentItem(currentItem);// 切换到下一个页面
removeCallbacks(nextPage);
postDelayed(nextPage, intervalTime);
}
}
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (!mNeedLoop) return;
if (visibility == VISIBLE) {
needSwitchPage = true;
postDelayed(nextPage, intervalTime);
} else {
needSwitchPage = false;
removeCallbacks(nextPage);
}
Log.d(TAG, "onVisibilityChanged visibility:" + visibility);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
needSwitchPage = false;
removeCallbacks(nextPage);
}
/**
* 初始化圆点尺寸 水平间隔
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDotRadius = h / 2;
mHorizontalSpacing = (int) (mDotRadius * 1.5f);
mDistanceOfDot = mDotRadius * 2 + mHorizontalSpacing;
}
}
几个自定义属性: