Skip to content

Commit

Permalink
customization ready
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonZorin committed Apr 20, 2016
1 parent 566c681 commit 7af17c5
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 65 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand All @@ -10,8 +11,18 @@
tools:context="com.antonzorin.dottedprogressbarexample.MainActivity">

<com.antonzorin.dottedprogressbar.DottedProgressBar
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_width="60dp"
android:layout_height="350dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
android:layout_centerVertical="true"
app:arrowHourPaddingPercent="40"
app:arrowMinutePaddingPercent="30"
app:arrowWidthPercent="14"
app:baseColor="#b41407"
app:arrowMinuteSpeed="20"
app:arrowHourSpeed="5"
app:clockwiseDots="true"
app:rotationSpeed="6"
app:maxDotsSizePercent="12"
app:minDotsSizePercent="5"/>
</RelativeLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
Expand All @@ -13,107 +14,139 @@
*/
public class DottedProgressBar extends View {

private Paint mPaint;
private Paint mDotsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mArrowsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

private float mMaxCircleSize;
private final int mCirclesCount = 12;
private float mCenter = 0;
private float mDegreePerCircle;
private int mDotsCount;
private float mCenter;
private float mSpaceBetweenDots;
private float mMinCircleSize;
private float mDeltaSize;
private float mMinuteArrowTopPadding;
private float mHourArrowTopPadding;
private float mArrowWidth;
private float mMituteArrowSpeed = 2f;
private float mHourArrowSpeed = 0.5f;
private float mHourArrowSpeed;
private float mMinuteArrowSpeed;
private float mMinuteArrowAngle;
private float mHourArrowAngle;

int iterator;
float time;
float timeThreshold = 3f;
private boolean isClockWiseDots;
private boolean isCounterClockWiseArrows;
private boolean hideArrows;
private int mMaxDotSizePercent;
private int mMinDotSizePercent;
private int mArrowWidthPercent;
private int mArrowHourPaddingPercent;
private int mArrowMinutePaddingPercent;
private float mRotationSpeed;

private int mIterator;
private float mTime;
private final float UPDATE_THRESHOLD = 3f;

public DottedProgressBar(Context context) {
super(context);
init();
init(context, null);
}

public DottedProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
init(context, attrs);
}

public DottedProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}

void init() {
void init(Context context, AttributeSet attrs) {
Resources r = getResources();

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DottedProgressBar);
int defaultColor = r.getColor(R.color.defaultColor);





mDegreePerCircle = 360 / mCirclesCount;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(getResources().getColor(R.color.defaultColor));
int defaultDotsCount = r.getInteger(R.integer.defaultDotsCount);
int defaultMaxDotSize = r.getInteger(R.integer.defaultMaxDotSize);
int defaultMinDotSize = r.getInteger(R.integer.defaultMinDotSize);
int defaultArrowWidthSize = r.getInteger(R.integer.defaultArrowWidthSize);
int defaultArrowHourPadding = r.getInteger(R.integer.defaultHourArrowPadding);
int defaultArrowMinutePadding = r.getInteger(R.integer.defaultMinuteArrowPadding);
int defaultHourArrowSpeed = r.getInteger(R.integer.defaultHourArrowSpeed);
int defaultMinuteArrowSpeed = r.getInteger(R.integer.defaultMinuteArrowSpeed);
int defaultRotationSpeed = r.getInteger(R.integer.defaultRotationSpeed);

mDotsPaint.setColor(a.getColor(R.styleable.DottedProgressBar_baseColor, defaultColor));
mCenterPaint.setColor(a.getColor(R.styleable.DottedProgressBar_centerColor, a.getColor(R.styleable.DottedProgressBar_baseColor, defaultColor)));
mArrowsPaint.setColor(a.getColor(R.styleable.DottedProgressBar_arrowsColor, a.getColor(R.styleable.DottedProgressBar_baseColor, defaultColor)));
isClockWiseDots = a.getBoolean(R.styleable.DottedProgressBar_clockwiseDots, false);
isCounterClockWiseArrows = a.getBoolean(R.styleable.DottedProgressBar_counterClockwiseArrows, false);
hideArrows = a.getBoolean(R.styleable.DottedProgressBar_hideArrows, false);
mDotsCount = a.getInteger(R.styleable.DottedProgressBar_dotsCount, defaultDotsCount);
mMaxDotSizePercent = a.getInteger(R.styleable.DottedProgressBar_maxDotsSizePercent, defaultMaxDotSize);
mMinDotSizePercent = a.getInteger(R.styleable.DottedProgressBar_minDotsSizePercent, defaultMinDotSize);
mArrowWidthPercent = a.getInteger(R.styleable.DottedProgressBar_arrowWidthPercent, defaultArrowWidthSize);
mArrowHourPaddingPercent = a.getInteger(R.styleable.DottedProgressBar_arrowHourPaddingPercent, defaultArrowHourPadding);
mArrowMinutePaddingPercent = a.getInteger(R.styleable.DottedProgressBar_arrowMinutePaddingPercent, defaultArrowMinutePadding);
mHourArrowSpeed = a.getInteger(R.styleable.DottedProgressBar_arrowHourSpeed, defaultHourArrowSpeed);
mHourArrowSpeed *= 0.1f;
mMinuteArrowSpeed = a.getInteger(R.styleable.DottedProgressBar_arrowMinuteSpeed, defaultMinuteArrowSpeed);
mMinuteArrowSpeed *= 0.1f;
mRotationSpeed = a.getInteger(R.styleable.DottedProgressBar_rotationSpeed, defaultRotationSpeed);
mRotationSpeed *= 0.1f;
mSpaceBetweenDots = 360 / mDotsCount;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h = MeasureSpec.getSize(heightMeasureSpec);
int result = Math.min(w, h);

mCenter = result * 0.5f;

mMaxCircleSize = result / 100 * 9.5f;//9.5% of size
mMinCircleSize = result / 100 * 3f; //3% of size
mDeltaSize = (mMaxCircleSize - mMinCircleSize) / mCirclesCount;

mMinuteArrowTopPadding = result / 100 * 20f;//20% of size
mHourArrowTopPadding = result / 100 * 25f;//25% of size
mArrowWidth = result / 100 * 7f;//7% of size

setMeasuredDimension(result, result);
int smallestSide = Math.min(w, h);

mCenter = smallestSide * 0.5f;
mMaxCircleSize = smallestSide / 100 * mMaxDotSizePercent;//10% of size
mMinCircleSize = smallestSide / 100 * mMinDotSizePercent; //3% of size
mDeltaSize = (mMaxCircleSize - mMinCircleSize) / mDotsCount;
mHourArrowTopPadding = smallestSide / 100 * mArrowHourPaddingPercent;//28% of size
mMinuteArrowTopPadding = smallestSide / 100 * mArrowMinutePaddingPercent;//23% of size
mArrowWidth = smallestSide / 100 * mArrowWidthPercent;//7% of size
setMeasuredDimension(smallestSide, smallestSide);
}

@Override
protected void onDraw(Canvas canvas) {

for (int i = (0 + iterator); i <= (mCirclesCount + iterator); i++) {
float circleSize = mMaxCircleSize - mDeltaSize * (i - iterator);
for (int i = (0 + mIterator); i <= (mDotsCount + mIterator); i++) {
float circleSize = mMaxCircleSize - mDeltaSize * (i - mIterator);
canvas.save();
float d = mDegreePerCircle * i;
canvas.rotate(-d, mCenter, mCenter);
canvas.drawCircle(mCenter, circleSize, circleSize, mPaint);
float speed = mSpaceBetweenDots * i;
canvas.rotate(isClockWiseDots ? speed : -speed, mCenter, mCenter);
canvas.drawCircle(mCenter, circleSize, circleSize, mDotsPaint);
invalidate();
canvas.restore();
}

time += 0.5f;
if (time >= timeThreshold) {
iterator++;
time = 0;
mTime += mRotationSpeed;
if (mTime >= UPDATE_THRESHOLD) {
mIterator++;
mTime = 0;
}
if (!hideArrows) {
//draw and animate minute arrow
canvas.save();
float mSpeed = mMinuteArrowAngle += mMinuteArrowSpeed;
canvas.rotate(isCounterClockWiseArrows ? -mSpeed : mSpeed, mCenter, mCenter);
canvas.drawRect(mCenter - mArrowWidth * 0.5f, mMinuteArrowTopPadding, mCenter + mArrowWidth * 0.5f, mCenter, mArrowsPaint);
invalidate();
canvas.restore();

//draw and animate minute arrow
canvas.save();
canvas.rotate(mMinuteArrowAngle += mMituteArrowSpeed, mCenter, mCenter);
canvas.drawRect(mCenter - mArrowWidth * 0.5f, mMinuteArrowTopPadding, mCenter + mArrowWidth * 0.5f, mCenter, mPaint);
invalidate();
canvas.restore();

//draw and animate hour arrow
canvas.save();
canvas.rotate(mHourArrowAngle += mHourArrowSpeed, mCenter, mCenter);
canvas.drawRect(mCenter - mArrowWidth * 0.5f, mHourArrowTopPadding, mCenter + mArrowWidth * 0.5f, mCenter, mPaint);
invalidate();
canvas.restore();

//draw center circle
canvas.drawCircle(mCenter, mCenter, mArrowWidth * 0.5f, mPaint);
//draw and animate hour arrow
canvas.save();
float hSpeed = mHourArrowAngle += mHourArrowSpeed;
canvas.rotate(isCounterClockWiseArrows ? -hSpeed : hSpeed, mCenter, mCenter);
canvas.drawRect(mCenter - mArrowWidth * 0.5f, mHourArrowTopPadding, mCenter + mArrowWidth * 0.5f, mCenter, mArrowsPaint);
invalidate();
canvas.restore();

//draw center circle
canvas.drawCircle(mCenter, mCenter, mArrowWidth * 0.5f, mCenterPaint);
}
}
}
15 changes: 14 additions & 1 deletion dottedprogressbar/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DottedProgressBar">
<attr name="dotColor" format="color"/>
<attr name="baseColor" format="color"/>
<attr name="arrowsColor" format="color"/>
<attr name="centerColor" format="color"/>
<attr name="clockwiseDots" format="boolean"/>
<attr name="counterClockwiseArrows" format="boolean"/>
<attr name="hideArrows" format="boolean"/>
<attr name="dotsCount" format="integer"/>
<attr name="maxDotsSizePercent" format="integer"/>
<attr name="minDotsSizePercent" format="integer"/>
<attr name="arrowWidthPercent" format="integer"/>
<attr name="arrowHourPaddingPercent" format="integer"/>
<attr name="arrowMinutePaddingPercent" format="integer"/>
<attr name="arrowHourSpeed" format="integer"/>
<attr name="arrowMinuteSpeed" format="integer"/>
<attr name="rotationSpeed" format="integer"/>

</declare-styleable>
</resources>
12 changes: 12 additions & 0 deletions dottedprogressbar/src/main/res/values/integers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="defaultDotsCount">12</integer>
<integer name="defaultMaxDotSize">10</integer>
<integer name="defaultMinDotSize">3</integer>
<integer name="defaultArrowWidthSize">7</integer>
<integer name="defaultHourArrowPadding">28</integer>
<integer name="defaultMinuteArrowPadding">23</integer>
<integer name="defaultHourArrowSpeed">5</integer>
<integer name="defaultMinuteArrowSpeed">20</integer>
<integer name="defaultRotationSpeed">6</integer>
</resources>

0 comments on commit 7af17c5

Please sign in to comment.