效果
public class IndicatorView extends LinearLayout implements ViewPager.OnPageChangeListener {
/**
* 需要创建的指示器个数
*/
private int childViewCount = 0;
/**
* 设置圆点间margin
*/
private int mInterval;
/**
* 当前选中的位置
*/
private int mCurrentPostion = 0;
/**
* 普通显示的图片
*/
private Bitmap normalBp;
/**
* 选中时显示的图片
*/
private Bitmap selectBp;
/**
* 设置的轮播图Vp
*/
private ViewPager mViewPager;
/**
* 指示器单项宽度
*/
private int mWidth;
/**
* 指示器单项高度
*/
private int mHeight;
/**
* 圆点半径
*/
private int mRadius;
/**
* 普通状态圆点颜色
*/
private int normalColor;
/**
* 选中状态圆点颜色
*/
private int selectColor;
/**
* 对外提供ViewPager的回调接口
*/
public interface OnPageChangeListener {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
public void onPageSelected(int position);
public void onPageScrollStateChanged(int state);
}
/**
* 回调接口
*/
private OnPageChangeListener mListener;
/**
* 设置回调
*
* @param listener
*/
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.mListener = listener;
}
public IndicatorView(Context context) {
this(context, null);
}
public IndicatorView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 获取自定义属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);
normalBp = drawableToBitamp(ta.getDrawable(R.styleable.IndicatorView_normalDrawable));
selectBp = drawableToBitamp(ta.getDrawable(R.styleable.IndicatorView_selectDrawable));
mInterval = ta.getDimensionPixelOffset(R.styleable.IndicatorView_indicatorInterval, 10);
normalColor = ta.getColor(R.styleable.IndicatorView_normalColor, context.getColor(R.color.backD1D1D1));
selectColor = ta.getColor(R.styleable.IndicatorView_selectColor, context.getColor(R.color.back8E8E8E));
mRadius = ta.getInteger(R.styleable.IndicatorView_indicatorRadius, 10);
ta.recycle();
// 初始化
init();
}
/**
* 初始化数据
*/
private void init() {
// 处理自定义属性
if (null == normalBp) {
normalBp = makeIndicatorBp(normalColor);
}
if (null == selectBp) {
selectBp = makeIndicatorBp(selectColor);
}
mWidth = normalBp.getWidth();
mHeight = normalBp.getWidth();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
// 如果是wrap_content设置为图片宽高,否则设置为父容器宽高
setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : (mWidth + mInterval) * childViewCount
, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight
: mHeight);
}
/**
* 重绘
*
* @param canvas
*/
@Override
protected void dispatchDraw(Canvas canvas) {
// 创建指示器圆点
if (getChildCount() < childViewCount && getChildCount() == 0) {
for (int i = 0; i < childViewCount; i++) {
addView(makeIndicatorItem());
}
// 设置默认选中指示器
setIndicatorState(mCurrentPostion);
}
super.dispatchDraw(canvas);
}
/**
* 设置Vp
*
* @param viewpager
*/
public void setViewPager(ViewPager viewpager) {
if (null == viewpager) {
return;
}
if (null == viewpager.getAdapter()) {
throw new IllegalStateException("ViewPager does not have adapter.");
}
this.mViewPager = viewpager;
this.mViewPager.addOnPageChangeListener(this);
this.childViewCount = viewpager.getAdapter().getCount();
invalidate();
}
/**
* 设置Vp
*
* @param viewpager
* @param currposition 当前选中的位置
*/
public void setViewPager(ViewPager viewpager, int currposition) {
if (null == viewpager) {
return;
}
if (null == viewpager.getAdapter()) {
throw new IllegalStateException("ViewPager does not have adapter.");
}
this.mViewPager = viewpager;
this.mViewPager.addOnPageChangeListener(this);
this.childViewCount = viewpager.getAdapter().getCount();
this.mCurrentPostion = currposition;
invalidate();
}
/**
* 创建指示器
*
* @return
*/
private View makeIndicatorItem() {
ImageView iv = new ImageView(getContext());
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.width = normalBp.getWidth();
lp.height = normalBp.getHeight();
lp.rightMargin = mInterval;
iv.setImageBitmap(normalBp);
iv.setLayoutParams(lp);
return iv;
}
/**
* 创建圆点指示器图片
*
* @param color 创建不同颜色的指示器项
* @return
*/
private Bitmap makeIndicatorBp(int color) {
Bitmap normalBp = Bitmap.createBitmap(mRadius * 2, mRadius * 2,
Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(color);
Canvas canvas = new Canvas(normalBp);
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
return normalBp;
}
/**
* drawable转bitmap
*
* @param drawable
* @return
*/
private Bitmap drawableToBitamp(Drawable drawable) {
if (null == drawable) {
return null;
}
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (null != mListener) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
setIndicatorState(position);
if (null != mListener) {
mListener.onPageSelected(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
if (null != mListener) {
mListener.onPageScrollStateChanged(state);
}
}
/**
* 设置指示器的状态
*
* @param position
*/
public void setIndicatorState(int position) {
for (int i = 0; i < getChildCount(); i++) {
if (i == position)
((ImageView) getChildAt(i)).setImageBitmap(selectBp);
else
((ImageView) getChildAt(i)).setImageBitmap(normalBp);
}
}
在布局引用IndicatorView就可以了
activity
idvBanner.setViewPager(mViewpager);//指示器
//指示器事件
idvBanner.setOnPageChangeListener(new IndicatorView.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
attrs
<!--IndicatorView相关-->
<!--普通指示器图片-->
<attr name="normalDrawable" format="reference"/>
<!--选中指示器图片-->
<attr name="selectDrawable" format="reference"/>
<!--指示器间隔-->
<attr name="indicatorInterval" format="dimension"/>
<!--普通指示器颜色-->
<attr name="normalColor" format="color"/>
<!--选中指示器颜色-->
<attr name="selectColor" format="color"/>
<!--圆点弧度-->
<attr name="indicatorRadius" format="integer"/>
<declare-styleable name="IndicatorView">
<attr name="normalDrawable"/>
<attr name="selectDrawable"/>
<attr name="indicatorInterval"/>
<attr name="normalColor"/>
<attr name="selectColor"/>
<attr name="indicatorRadius"/>
</declare-styleable>