diff --git a/CHANGELOG.md b/CHANGELOG.md
index f94d68f..4fb61d3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+##0.5.0
+
+- Added a gradient option via XML and JAVA
+
##0.4.0
- Added a `progressStart()` and `progressStop()` methods
diff --git a/gradle.properties b/gradle.properties
index dfab4a2..c41fcb3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
-VERSION_NAME=0.5.0-SNAPSHOT
-VERSION_CODE=12
+VERSION_NAME=0.5.0
+VERSION_CODE=13
BUILD_TOOLS_VERSION=19.0.3
COMPILE_SDK_VERSION=19
GROUP=com.github.castorflex.smoothprogressbar
diff --git a/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressBar.java b/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressBar.java
index 3949e34..c359be9 100644
--- a/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressBar.java
+++ b/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressBar.java
@@ -57,6 +57,7 @@ public SmoothProgressBar(Context context, AttributeSet attrs, int defStyle) {
final boolean progressiveStartActivated = a.getBoolean(R.styleable.SmoothProgressBar_spb_progressiveStart_activated, res.getBoolean(R.bool.spb_default_progressiveStart_activated));
final Drawable backgroundDrawable = a.getDrawable(R.styleable.SmoothProgressBar_spb_background);
final boolean generateBackgroundWithColors = a.getBoolean(R.styleable.SmoothProgressBar_spb_generate_background_with_colors, false);
+ final boolean gradients = a.getBoolean(R.styleable.SmoothProgressBar_spb_gradients, false);
a.recycle();
//interpolator
@@ -97,7 +98,8 @@ public SmoothProgressBar(Context context, AttributeSet attrs, int defStyle) {
.strokeWidth(strokeWidth)
.reversed(reversed)
.mirrorMode(mirrorMode)
- .progressiveStart(progressiveStartActivated);
+ .progressiveStart(progressiveStartActivated)
+ .gradients(gradients);
if (backgroundDrawable != null) {
builder.backgroundDrawable(backgroundDrawable);
@@ -157,8 +159,11 @@ public void applyStyle(int styleResId) {
if (a.hasValue(R.styleable.SmoothProgressBar_spb_progressiveStart_activated)) {
setProgressiveStartActivated(a.getBoolean(R.styleable.SmoothProgressBar_spb_progressiveStart_activated, false));
}
- if (a.hasValue(R.styleable.SmoothProgressBar_spb_background)) {
- setSmoothProgressDrawableBackgroundDrawable(a.getDrawable(R.styleable.SmoothProgressBar_spb_background));
+ if (a.hasValue(R.styleable.SmoothProgressBar_spb_progressiveStart_activated)) {
+ setProgressiveStartActivated(a.getBoolean(R.styleable.SmoothProgressBar_spb_progressiveStart_activated, false));
+ }
+ if (a.hasValue(R.styleable.SmoothProgressBar_spb_gradients)) {
+ setSmoothProgressDrawableUseGradients(a.getBoolean(R.styleable.SmoothProgressBar_spb_gradients, false));
}
if (a.hasValue(R.styleable.SmoothProgressBar_spb_generate_background_with_colors)) {
if (a.getBoolean(R.styleable.SmoothProgressBar_spb_generate_background_with_colors, false)) {
@@ -272,6 +277,10 @@ public void setSmoothProgressDrawableBackgroundDrawable(Drawable drawable) {
checkIndeterminateDrawable().setBackgroundDrawable(drawable);
}
+ public void setSmoothProgressDrawableUseGradients(boolean useGradients) {
+ checkIndeterminateDrawable().setUseGradients(useGradients);
+ }
+
public void progressiveStart() {
checkIndeterminateDrawable().progressiveStart();
}
diff --git a/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressDrawable.java b/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressDrawable.java
index e609663..af01ed2 100644
--- a/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressDrawable.java
+++ b/library/src/main/java/fr/castorflex/android/smoothprogressbar/SmoothProgressDrawable.java
@@ -4,9 +4,11 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.Shader;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
@@ -52,6 +54,9 @@ public interface Callbacks {
private int mCurrentSections;
private float mStrokeWidth;
private Drawable mBackgroundDrawable;
+ private boolean mUseGradients;
+ private int[] mLinearGradientColors;
+ private float[] mLinearGradientPositions;
private SmoothProgressDrawable(Interpolator interpolator,
@@ -66,7 +71,8 @@ private SmoothProgressDrawable(Interpolator interpolator,
boolean mirrorMode,
Callbacks callbacks,
boolean progressiveStartActivated,
- Drawable backgroundDrawable) {
+ Drawable backgroundDrawable,
+ boolean useGradients) {
mRunning = false;
mInterpolator = interpolator;
mSectionsCount = sectionsCount;
@@ -94,6 +100,9 @@ private SmoothProgressDrawable(Interpolator interpolator,
mProgressiveStartActivated = progressiveStartActivated;
mCallbacks = callbacks;
+
+ mUseGradients = useGradients;
+ refreshLinearGradientOptions();
}
////////////////////////////////////////////////////////////////////////////
@@ -109,6 +118,7 @@ public void setColors(int[] colors) {
throw new IllegalArgumentException("Colors cannot be null or empty");
mColorsIndex = 0;
mColors = colors;
+ refreshLinearGradientOptions();
invalidateSelf();
}
@@ -139,6 +149,7 @@ public void setSectionsCount(int sectionsCount) {
mSectionsCount = sectionsCount;
mMaxOffset = 1f / mSectionsCount;
mCurrentOffset %= mMaxOffset;
+ refreshLinearGradientOptions();
invalidateSelf();
}
@@ -189,6 +200,25 @@ public void setProgressiveStartActivated(boolean progressiveStartActivated) {
mProgressiveStartActivated = progressiveStartActivated;
}
+ public void setUseGradients(boolean useGradients) {
+ if (mUseGradients == useGradients) return;
+
+ mUseGradients = useGradients;
+ refreshLinearGradientOptions();
+ invalidateSelf();
+ }
+
+ protected void refreshLinearGradientOptions() {
+ if (mUseGradients) {
+ mLinearGradientColors = new int[mSectionsCount + 2];
+ mLinearGradientPositions = new float[mSectionsCount + 2];
+ } else {
+ mPaint.setShader(null);
+ mLinearGradientColors = null;
+ mLinearGradientPositions = null;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////
/////////////////// DRAW
@@ -197,24 +227,6 @@ public void draw(Canvas canvas) {
mBounds = getBounds();
canvas.clipRect(mBounds);
- int boundsWidth = mBounds.width();
-
- if (mReversed) {
- canvas.translate(boundsWidth, 0);
- canvas.scale(-1, 1);
- }
-
- drawStrokes(canvas);
- }
-
- private void drawStrokes(Canvas canvas) {
- float prevValue = 0f;
- int boundsWidth = mBounds.width();
- if (mMirrorMode) boundsWidth /= 2;
- int width = boundsWidth + mSeparatorLength + mSectionsCount;
- int centerY = mBounds.centerY();
- float xSectionWidth = 1f / mSectionsCount;
-
//new turn
if (mNewTurn) {
mColorsIndex = decrementColor(mColorsIndex);
@@ -233,6 +245,58 @@ private void drawStrokes(Canvas canvas) {
}
}
+ if (mUseGradients)
+ drawGradient(canvas);
+
+ drawStrokes(canvas);
+ }
+
+ private void drawGradient(Canvas canvas) {
+ float xSectionWidth = 1f / mSectionsCount;
+ int currentIndexColor = mColorsIndex;
+
+ mLinearGradientPositions[0] = 0f;
+ mLinearGradientPositions[mLinearGradientPositions.length - 1] = 1f;
+ int firstColorIndex = currentIndexColor - 1;
+ if (firstColorIndex < 0) firstColorIndex += mColors.length;
+
+ mLinearGradientColors[0] = mColors[firstColorIndex];
+
+ for (int i = 0; i < mSectionsCount; ++i) {
+
+ float position = mInterpolator.getInterpolation(i * xSectionWidth + mCurrentOffset);
+ mLinearGradientPositions[i + 1] = position;
+ mLinearGradientColors[i + 1] = mColors[currentIndexColor];
+
+ currentIndexColor = (currentIndexColor + 1) % mColors.length;
+ }
+ mLinearGradientColors[mLinearGradientColors.length - 1] = mColors[currentIndexColor];
+
+ float left = mReversed ? (mMirrorMode ? Math.abs(mBounds.left - mBounds.right) / 2 : mBounds.right) : mBounds.left;
+ float right = mMirrorMode ? (mReversed ? mBounds.left : Math.abs(mBounds.left - mBounds.right) / 2) :
+ (mReversed ? mBounds.left : mBounds.right);
+ float top = mBounds.centerY() - mStrokeWidth / 2;
+ float bottom = mBounds.centerY() + mStrokeWidth / 2;
+ LinearGradient linearGradient = new LinearGradient(left, top, right, bottom,
+ mLinearGradientColors, mLinearGradientPositions,
+ mMirrorMode ? Shader.TileMode.MIRROR : Shader.TileMode.CLAMP);
+
+ mPaint.setShader(linearGradient);
+ }
+
+ private void drawStrokes(Canvas canvas) {
+ if (mReversed) {
+ canvas.translate(mBounds.width(), 0);
+ canvas.scale(-1, 1);
+ }
+
+ float prevValue = 0f;
+ int boundsWidth = mBounds.width();
+ if (mMirrorMode) boundsWidth /= 2;
+ int width = boundsWidth + mSeparatorLength + mSectionsCount;
+ int centerY = mBounds.centerY();
+ float xSectionWidth = 1f / mSectionsCount;
+
float startX;
float endX;
float firstX = 0;
@@ -547,6 +611,7 @@ public static class Builder {
private int mStrokeSeparatorLength;
private boolean mProgressiveStartActivated;
private boolean mGenerateBackgroundUsingColors;
+ private boolean mGradients;
private Drawable mBackgroundDrawableWhenHidden;
private Callbacks mOnProgressiveStopEndedListener;
@@ -572,7 +637,8 @@ public SmoothProgressDrawable build() {
mMirrorMode,
mOnProgressiveStopEndedListener,
mProgressiveStartActivated,
- mBackgroundDrawableWhenHidden);
+ mBackgroundDrawableWhenHidden,
+ mGradients);
return ret;
}
@@ -588,6 +654,7 @@ private void initValues(Context context) {
mStrokeSeparatorLength = res.getDimensionPixelSize(R.dimen.spb_default_stroke_separator_length);
mStrokeWidth = res.getDimensionPixelOffset(R.dimen.spb_default_stroke_width);
mProgressiveStartActivated = res.getBoolean(R.bool.spb_default_progressiveStart_activated);
+ mGradients = false;
}
public Builder interpolator(Interpolator interpolator) {
@@ -677,5 +744,14 @@ public Builder generateBackgroundUsingColors() {
mGenerateBackgroundUsingColors = true;
return this;
}
+
+ public Builder gradients() {
+ return gradients(true);
+ }
+
+ public Builder gradients(boolean useGradients) {
+ mGradients = useGradients;
+ return this;
+ }
}
}
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
index a037423..0d309c5 100644
--- a/library/src/main/res/values/attrs.xml
+++ b/library/src/main/res/values/attrs.xml
@@ -21,5 +21,6 @@
+
\ No newline at end of file
diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml
index 3b91cb9..1816559 100644
--- a/library/src/main/res/values/styles.xml
+++ b/library/src/main/res/values/styles.xml
@@ -16,6 +16,7 @@
- @bool/spb_default_progressiveStart_activated
- @null
- false
+ - false
\ No newline at end of file
diff --git a/sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/MakeCustomActivity.java b/sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/MakeCustomActivity.java
index 5621d91..fcb7363 100644
--- a/sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/MakeCustomActivity.java
+++ b/sample/src/main/java/fr/castorflex/android/smoothprogressbar/sample/MakeCustomActivity.java
@@ -27,6 +27,7 @@ public class MakeCustomActivity extends Activity {
private SmoothProgressBar mProgressBar;
private CheckBox mCheckBoxMirror;
private CheckBox mCheckBoxReversed;
+ private CheckBox mCheckBoxGradients;
private Spinner mSpinnerInterpolators;
private SeekBar mSeekBarSectionsCount;
private SeekBar mSeekBarStrokeWidth;
@@ -52,6 +53,7 @@ protected void onCreate(Bundle savedInstanceState) {
mProgressBar = (SmoothProgressBar) findViewById(R.id.progressbar);
mCheckBoxMirror = (CheckBox) findViewById(R.id.checkbox_mirror);
mCheckBoxReversed = (CheckBox) findViewById(R.id.checkbox_reversed);
+ mCheckBoxGradients = (CheckBox) findViewById(R.id.checkbox_gradients);
mSpinnerInterpolators = (Spinner) findViewById(R.id.spinner_interpolator);
mSeekBarSectionsCount = (SeekBar) findViewById(R.id.seekbar_sections_count);
mSeekBarStrokeWidth = (SeekBar) findViewById(R.id.seekbar_stroke_width);
@@ -159,6 +161,7 @@ private void setValues() {
mProgressBar.setSmoothProgressDrawableStrokeWidth(dpToPx(mStrokeWidth));
mProgressBar.setSmoothProgressDrawableReversed(mCheckBoxReversed.isChecked());
mProgressBar.setSmoothProgressDrawableMirrorMode(mCheckBoxMirror.isChecked());
+ mProgressBar.setSmoothProgressDrawableUseGradients(mCheckBoxGradients.isChecked());
Interpolator interpolator;
switch (mSpinnerInterpolators.getSelectedItemPosition()) {
diff --git a/sample/src/main/res/layout/activity_custom.xml b/sample/src/main/res/layout/activity_custom.xml
index 022e26c..e10e738 100644
--- a/sample/src/main/res/layout/activity_custom.xml
+++ b/sample/src/main/res/layout/activity_custom.xml
@@ -38,6 +38,13 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Mirror Mode"/>
+
+
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
index 9f4be7b..3d3c9f6 100644
--- a/sample/src/main/res/layout/activity_main.xml
+++ b/sample/src/main/res/layout/activity_main.xml
@@ -67,6 +67,18 @@
style="@style/GNowProgressBar"
android:indeterminate="true"/>
+
+
+
+
false
+
+