package com.github.captain_miao.agera.tutorial.viewpage;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
/**
*
*/
public class ViewPageDotView extends View {
public static int DEFAULT_RADIUS = 8;
public static int DEFAULT_STROKE_COLOR = Color.parseColor("#999999");
public static int DEFAULT_FILL_COLOR = Color.parseColor("#ffffff");
private int mNumOfCircles = 0;
private int mScreenWidth;
private float mRadius = DEFAULT_RADIUS;
private float mDistance;
private float[] mXPositions;
private float mYPositions;
private float mLeftOrRightSpace;
private float mAllDotsDomainLength;
private float mOnceMovedTotalDistance;
private Paint mPaintStroke;
private int mStrokeColor = DEFAULT_STROKE_COLOR;
private Paint mPaintFill;
private int mFillColor = DEFAULT_FILL_COLOR;
private float mScrollRatio; // current drag ratio
private int mCurrentIndex;
private int mState;
public ViewPageDotView(Context context) {
this(context, (AttributeSet) null);
}
public ViewPageDotView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
initLengthRelatedVariables();
}
public void setNumOfCircles(int numOfCircles){
setNumOfCircles(numOfCircles, DEFAULT_RADIUS);
}
public void setNumOfCircles(int numOfCircles, float radius) {
if (numOfCircles <= 1) {
this.setVisibility(View.INVISIBLE);
return;
}
this.mRadius = radius;
initLengthRelatedVariables();
mNumOfCircles = numOfCircles;
mAllDotsDomainLength = 2 * mRadius * mNumOfCircles + mDistance * (mNumOfCircles - 1);
mLeftOrRightSpace = (mScreenWidth - mAllDotsDomainLength) / 2.0f;
mXPositions = new float[mNumOfCircles];
for (int i = 0; i < mNumOfCircles; i++) {
mXPositions[i] = mLeftOrRightSpace + mRadius * (i * 2 + 1) + mDistance * i;
}
}
/**
* 设置画笔相关变量
*/
private void initPaint() {
mPaintStroke = new Paint();
mPaintStroke.setColor(mStrokeColor);
mPaintStroke.setAntiAlias(true);
mPaintFill = new Paint();
mPaintFill.setColor(mFillColor);
mPaintFill.setAntiAlias(true);
}
/**
* 设置距离相关变量
*/
private void initLengthRelatedVariables() {
mScreenWidth = getResources().getDisplayMetrics().widthPixels;
mDistance = mRadius * 2;
mYPositions = mRadius;
mOnceMovedTotalDistance = mRadius * 2 + mDistance;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawStrokeCircle(canvas);
drawFillCircle(canvas);
}
/**
* 绘制静态圆点
*
* @param canvas
*/
private void drawStrokeCircle(Canvas canvas) {
if (mNumOfCircles <= 0) {
return;
}
for (int i = 0; i < mNumOfCircles; i++) {
canvas.drawCircle(mXPositions[i], mYPositions, mRadius, mPaintStroke);
}
}
/**
* 绘制动态圆点
*
* @param canvas
*/
private void drawFillCircle(Canvas canvas) {
if (mNumOfCircles <= 0) {
return;
}
float offset = mLeftOrRightSpace + mRadius + mCurrentIndex * mOnceMovedTotalDistance + mScrollRatio * mOnceMovedTotalDistance;
if (offset < mLeftOrRightSpace + mRadius) {
offset = mLeftOrRightSpace + mRadius;
}
if (offset > (mLeftOrRightSpace + mRadius) + (mNumOfCircles - 1) * mOnceMovedTotalDistance) {
offset = mLeftOrRightSpace + mRadius + (mNumOfCircles - 1) * mOnceMovedTotalDistance;
}
canvas.drawCircle(offset, mYPositions, mRadius, mPaintFill);
}
public void onPageScrolled(int canSeePageIndex, float v, int i2) {
mScrollRatio = v;
mCurrentIndex = canSeePageIndex;
invalidate();
}
public void onPageSelected(int currentIndex) {
if (mState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentIndex = currentIndex;
invalidate();
}
}
public void onPageScrollStateChanged(int i) {
mState = i;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
ViewPageDotView.SavedState savedState = (ViewPageDotView.SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentIndex = savedState.currentPage;
this.requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
ViewPageDotView.SavedState savedState = new ViewPageDotView.SavedState(superState);
savedState.currentPage = this.mCurrentIndex;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
public ViewPageDotView.SavedState createFromParcel(Parcel in) {
return new ViewPageDotView.SavedState(in);
}
public ViewPageDotView.SavedState[] newArray(int size) {
return new ViewPageDotView.SavedState[size];
}
};
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.currentPage = in.readInt();
}
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.currentPage);
}
}
}