diff --git a/README.md b/README.md
index 2463619..4fe095b 100644
--- a/README.md
+++ b/README.md
@@ -91,6 +91,9 @@ circularProgress.setProgress(5000, 10000);
// you can get progress values using following getters
circularProgress.getProgress() // returns 5000
circularProgress.getMaxProgress() // returns 10000
+
+// you can also set a visual gap between the progress and background strokes
+circularProgress.setProgressGap(100);
```
#### Attributes
@@ -105,6 +108,7 @@ circularProgress.getMaxProgress() // returns 10000
| Dot width | `app:dotWidth` | setters: `setDotWidthDp(widthInDp)` or `setDotWidthPx(widthInPx)`
getter: `getDotWidth()` (returns width in pixels) | same as progress stroke width |
| Progress text size | `app:textSize` | setters: `setTextSizeSp(sizeInSp)` or `setTextSizePx(sizeInPx)`
getter: `getTextSize()` (returns size in pixels) | `24sp` |
| Progress text color | `app:textColor` | setter: `setTextColor(textColor)`
getter: `getTextColor()` | same as progress color |
+| Whether to show text | `app:showText` | setter: `setShowTextEnabled(enabled)`
getter: `isShowTextEnabled()` | `true` |
| Formatting pattern to be used in `PatternProgressTextAdapter`. Checkout [Formatting progress text](#formatting-progress-text) section. | `app:formattingPattern` | setter: `setProgressTextAdapter(progressTextAdapter)`
getter: `getProgressTextAdapter()` | not specified |
| Direction of the progress arc (`clockwise` or `counterclockwise`) | `app:direction` | setter: `setDirection(direction)`
getter: `getDirection()` | `counterclockwise` |
| Start angle. Checkout [Start angle](#setting-start-angle) section. | `app:startAngle` | setter: `setStartAngle(startAngle)`
getter: `getStartAngle()` | `270` |
@@ -245,6 +249,11 @@ circularProgress.setGradient(gradientType, endColor);
circularProgress.getGradientType(); //returns LINEAR_GRADIENT
```
+Or, for advanced gradients with multiple colors and optional color positions, in code:
+```java
+circularProgress.setGradient(type, new int[]{Color.BLUE, Color.MAGENTA, Color.RED}, new float[]{0f, .3f, .7f});
+```
+
---
### Download using Gradle
diff --git a/build.gradle b/build.gradle
index 0dec223..4f923ee 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.3'
+ classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/circularprogressindicator/build.gradle b/circularprogressindicator/build.gradle
index 00cf015..784e861 100644
--- a/circularprogressindicator/build.gradle
+++ b/circularprogressindicator/build.gradle
@@ -1,15 +1,11 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
-group='com.github.antonKozyriatskyi.CircularProgressIndicator'
android {
- compileSdkVersion 27
+ compileSdkVersion 31
defaultConfig {
minSdkVersion 15
- targetSdkVersion 27
- versionCode 1
- versionName "1.0"
}
buildTypes {
@@ -23,5 +19,5 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.android.support:support-annotations:27.1.1'
+ implementation 'androidx.annotation:annotation:1.3.0'
}
diff --git a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/CircularProgressIndicator.java b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/CircularProgressIndicator.java
index 28e44e4..f9ab977 100644
--- a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/CircularProgressIndicator.java
+++ b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/CircularProgressIndicator.java
@@ -4,6 +4,7 @@
import android.animation.PropertyValuesHolder;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
@@ -18,12 +19,6 @@
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.os.Build;
-import android.support.annotation.ColorInt;
-import android.support.annotation.Dimension;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -32,6 +27,14 @@
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
+import androidx.annotation.ColorInt;
+import androidx.annotation.Dimension;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.Size;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -39,7 +42,7 @@
* Created by Anton on 03.03.2018.
*/
-@SuppressWarnings("FieldCanBeLocal")
+@SuppressWarnings({"FieldCanBeLocal", "unused"})
public class CircularProgressIndicator extends View {
public static final int DIRECTION_CLOCKWISE = 0;
@@ -75,7 +78,7 @@ public class CircularProgressIndicator extends View {
private Paint textPaint;
private int startAngle = DEFAULT_PROGRESS_START_ANGLE;
- private int sweepAngle = 0;
+ private float sweepAngle = 0;
private RectF circleBounds;
@@ -89,16 +92,22 @@ public class CircularProgressIndicator extends View {
private double maxProgressValue = 100.0;
private double progressValue = 0.0;
+ private double progressGap = 0.0;
private boolean isAnimationEnabled;
private boolean isFillBackgroundEnabled;
+ private int animationDuration = DEFAULT_ANIMATION_DURATION;
+
+ private boolean isShowTextEnabled = true;
+
@Direction
private int direction = DIRECTION_COUNTERCLOCKWISE;
private ValueAnimator progressAnimator;
+ @SuppressWarnings("NotNullFieldNotInitialized") // initialized in init method
@NonNull
private ProgressTextAdapter progressTextAdapter;
@@ -108,6 +117,9 @@ public class CircularProgressIndicator extends View {
@NonNull
private Interpolator animationInterpolator = new AccelerateDecelerateInterpolator();
+ @NonNull
+ private final Rect textBoundsRect = new Rect();
+
public CircularProgressIndicator(Context context) {
super(context);
init(context, null);
@@ -165,6 +177,7 @@ private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
isAnimationEnabled = a.getBoolean(R.styleable.CircularProgressIndicator_enableProgressAnimation, true);
isFillBackgroundEnabled = a.getBoolean(R.styleable.CircularProgressIndicator_fillBackground, false);
+ isShowTextEnabled = a.getBoolean(R.styleable.CircularProgressIndicator_showText, true);
direction = a.getInt(R.styleable.CircularProgressIndicator_direction, DIRECTION_COUNTERCLOCKWISE);
@@ -188,12 +201,7 @@ private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
throw new IllegalArgumentException("did you forget to specify gradientColorEnd?");
}
- post(new Runnable() {
- @Override
- public void run() {
- setGradient(gradientType, gradientColorEnd);
- }
- });
+ post(() -> setGradient(gradientType, gradientColorEnd));
}
a.recycle();
@@ -208,6 +216,7 @@ public void run() {
Paint.Style progressBackgroundStyle = isFillBackgroundEnabled ? Paint.Style.FILL_AND_STROKE : Paint.Style.STROKE;
progressBackgroundPaint = new Paint();
+ progressBackgroundPaint.setStrokeCap(progressStrokeCap);
progressBackgroundPaint.setStyle(progressBackgroundStyle);
progressBackgroundPaint.setStrokeWidth(progressBackgroundStrokeWidth);
progressBackgroundPaint.setColor(progressBackgroundColor);
@@ -229,6 +238,7 @@ public void run() {
circleBounds = new RectF();
}
+ @SuppressLint("SwitchIntDef")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -244,10 +254,8 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- Rect textBoundsRect = new Rect();
textPaint.getTextBounds(progressText, 0, progressText.length(), textBoundsRect);
-
float dotWidth = dotPaint.getStrokeWidth();
float progressWidth = progressPaint.getStrokeWidth();
float progressBackgroundWidth = progressBackgroundPaint.getStrokeWidth();
@@ -335,12 +343,26 @@ protected void onDraw(Canvas canvas) {
drawProgressBackground(canvas);
drawProgress(canvas);
if (shouldDrawDot) drawDot(canvas);
- drawText(canvas);
+ if (isShowTextEnabled) drawText(canvas);
}
private void drawProgressBackground(Canvas canvas) {
- canvas.drawArc(circleBounds, ANGLE_START_PROGRESS_BACKGROUND, ANGLE_END_PROGRESS_BACKGROUND,
- false, progressBackgroundPaint);
+ if (progressGap == 0) {
+ canvas.drawArc(circleBounds, ANGLE_START_PROGRESS_BACKGROUND, ANGLE_END_PROGRESS_BACKGROUND,
+ false, progressBackgroundPaint);
+ } else {
+ float gapAngle = (float) (progressGap / maxProgressValue * 360);
+
+ float startAngle = this.sweepAngle + this.startAngle + gapAngle;
+ float sweepAngle = 360 - this.sweepAngle - 2 * gapAngle;
+
+ if (sweepAngle < 0) {
+ return;
+ }
+
+ canvas.drawArc(circleBounds, startAngle, sweepAngle,
+ false, progressBackgroundPaint);
+ }
}
private void drawProgress(Canvas canvas) {
@@ -403,34 +425,27 @@ public void setProgress(double current, double max) {
if (isAnimationEnabled) {
startProgressAnimation(oldCurrentProgress, finalAngle);
} else {
- sweepAngle = (int) finalAngle;
+ sweepAngle = (float) finalAngle;
invalidate();
}
}
private void startProgressAnimation(double oldCurrentProgress, final double finalAngle) {
- final PropertyValuesHolder angleProperty = PropertyValuesHolder.ofInt(PROPERTY_ANGLE, sweepAngle, (int) finalAngle);
+ final PropertyValuesHolder angleProperty = PropertyValuesHolder.ofFloat(PROPERTY_ANGLE, sweepAngle, (float) finalAngle);
- progressAnimator = ValueAnimator.ofObject(new TypeEvaluator() {
- @Override
- public Double evaluate(float fraction, Double startValue, Double endValue) {
- return (startValue + (endValue - startValue) * fraction);
- }
- }, oldCurrentProgress, progressValue);
- progressAnimator.setDuration(DEFAULT_ANIMATION_DURATION);
+ progressAnimator = ValueAnimator.ofObject((TypeEvaluator)
+ (fraction, startValue, endValue) -> (startValue + (endValue - startValue) * fraction), oldCurrentProgress, progressValue);
+ progressAnimator.setDuration(animationDuration);
progressAnimator.setValues(angleProperty);
progressAnimator.setInterpolator(animationInterpolator);
- progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- sweepAngle = (int) animation.getAnimatedValue(PROPERTY_ANGLE);
- invalidate();
- }
+ progressAnimator.addUpdateListener(animation -> {
+ sweepAngle = (float) animation.getAnimatedValue(PROPERTY_ANGLE);
+ invalidate();
});
progressAnimator.addListener(new DefaultAnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
- sweepAngle = (int) finalAngle;
+ sweepAngle = (float) finalAngle;
invalidate();
progressAnimator = null;
}
@@ -621,7 +636,6 @@ public float getDotWidth() {
return dotPaint.getStrokeWidth();
}
-
public double getProgress() {
return progressValue;
}
@@ -658,6 +672,7 @@ public void setProgressStrokeCap(@Cap int cap) {
Paint.Cap paintCap = (cap == CAP_ROUND) ? Paint.Cap.ROUND : Paint.Cap.BUTT;
if (progressPaint.getStrokeCap() != paintCap) {
progressPaint.setStrokeCap(paintCap);
+ progressBackgroundPaint.setStrokeCap(paintCap);
invalidate();
}
}
@@ -696,6 +711,24 @@ public boolean isFillBackgroundEnabled() {
return isFillBackgroundEnabled;
}
+ public void setShowTextEnabled(boolean enabled) {
+ if (isShowTextEnabled == enabled) return;
+ isShowTextEnabled = enabled;
+ invalidateEverything();
+ }
+
+ public boolean isShowTextEnabled() {
+ return isShowTextEnabled;
+ }
+
+ public void setAnimationDuration(int duration) {
+ animationDuration = duration;
+ }
+
+ public int getAnimationDuration() {
+ return animationDuration;
+ }
+
public void setInterpolator(@NonNull Interpolator interpolator) {
animationInterpolator = interpolator;
}
@@ -706,23 +739,28 @@ public Interpolator getInterpolator() {
}
public void setGradient(@GradientType int type, @ColorInt int endColor) {
+ int startColor = progressPaint.getColor();
+ setGradient(type, new int[]{startColor, endColor}, null);
+ }
+
+ public void setGradient(@GradientType int type, @Size(min = 2) @ColorInt int[] colors, @Nullable float[] positions) {
Shader gradient = null;
float cx = getWidth() / 2f;
float cy = getHeight() / 2f;
- int startColor = progressPaint.getColor();
-
switch (type) {
case LINEAR_GRADIENT:
- gradient = new LinearGradient(0f, 0f, getWidth(), getHeight(), startColor, endColor, Shader.TileMode.CLAMP);
+ gradient = new LinearGradient(0f, 0f, getWidth(), getHeight(), colors, positions, Shader.TileMode.CLAMP);
break;
case RADIAL_GRADIENT:
- gradient = new RadialGradient(cx, cy, cx, startColor, endColor, Shader.TileMode.MIRROR);
+ gradient = new RadialGradient(cx, cy, cx, colors, positions, Shader.TileMode.MIRROR);
break;
case SWEEP_GRADIENT:
- gradient = new SweepGradient(cx, cy, new int[]{startColor, endColor}, null);
+ gradient = new SweepGradient(cx, cy, colors, positions);
break;
+ case NO_GRADIENT:
+ return;
}
if (gradient != null) {
@@ -753,6 +791,15 @@ public int getGradientType() {
return type;
}
+ public double getProgressGap() {
+ return progressGap;
+ }
+
+ public void setProgressGap(double progressGap) {
+ this.progressGap = progressGap;
+ invalidate();
+ }
+
@Retention(RetentionPolicy.SOURCE)
@IntDef({DIRECTION_CLOCKWISE, DIRECTION_COUNTERCLOCKWISE})
public @interface Direction {
diff --git a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/DefaultProgressTextAdapter.java b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/DefaultProgressTextAdapter.java
index acd8375..e515646 100644
--- a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/DefaultProgressTextAdapter.java
+++ b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/DefaultProgressTextAdapter.java
@@ -1,11 +1,14 @@
package antonkozyriatskyi.circularprogressindicator;
+import androidx.annotation.NonNull;
+
/**
* Created by Anton on 06.06.2018.
*/
public final class DefaultProgressTextAdapter implements CircularProgressIndicator.ProgressTextAdapter {
+ @NonNull
@Override
public String formatText(double currentProgress) {
return String.valueOf((int) currentProgress);
diff --git a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/PatternProgressTextAdapter.java b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/PatternProgressTextAdapter.java
index 617344c..037a5d4 100644
--- a/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/PatternProgressTextAdapter.java
+++ b/circularprogressindicator/src/main/java/antonkozyriatskyi/circularprogressindicator/PatternProgressTextAdapter.java
@@ -1,6 +1,6 @@
package antonkozyriatskyi.circularprogressindicator;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
/**
* Created by Anton on 06.06.2018.
@@ -8,7 +8,7 @@
public final class PatternProgressTextAdapter implements CircularProgressIndicator.ProgressTextAdapter {
- private String pattern;
+ private final String pattern;
public PatternProgressTextAdapter(String pattern) {
this.pattern = pattern;
diff --git a/circularprogressindicator/src/main/res/values/attrs.xml b/circularprogressindicator/src/main/res/values/attrs.xml
index 4a6986e..9622338 100644
--- a/circularprogressindicator/src/main/res/values/attrs.xml
+++ b/circularprogressindicator/src/main/res/values/attrs.xml
@@ -31,6 +31,7 @@
+
@@ -42,4 +43,4 @@
-
\ No newline at end of file
+
diff --git a/example/build.gradle b/example/build.gradle
index 924b8a7..dac7527 100644
--- a/example/build.gradle
+++ b/example/build.gradle
@@ -1,11 +1,11 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 27
+ compileSdkVersion 31
defaultConfig {
applicationId "antonkozyriatskyi.circularprogressindicatorexample"
minSdkVersion 15
- targetSdkVersion 27
+ targetSdkVersion 31
versionCode 1
versionName "1.0"
}
@@ -21,6 +21,6 @@ dependencies {
implementation project(':circularprogressindicator')
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.android.support:appcompat-v7:27.1.0'
- implementation 'com.android.support:design:27.1.0'
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'com.google.android.material:material:1.5.0'
}
diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml
index 580474d..8e3b35b 100644
--- a/example/src/main/AndroidManifest.xml
+++ b/example/src/main/AndroidManifest.xml
@@ -10,7 +10,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
-
+
diff --git a/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/ColorPickerDialogFragment.java b/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/ColorPickerDialogFragment.java
index 8790663..7b6805d 100644
--- a/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/ColorPickerDialogFragment.java
+++ b/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/ColorPickerDialogFragment.java
@@ -4,15 +4,17 @@
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.design.widget.BottomSheetDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.SeekBar;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
/**
* Created by Anton on 13.03.2018.
*/
@@ -55,25 +57,22 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
colorResult.setBackgroundColor(Color.rgb(redProgress, greenProgress, blueProgress));
- switch (seekBar.getId()) {
- case R.id.sb_red:
- seekBar.getProgressDrawable().setColorFilter(Color.rgb(redProgress, 0, 0), mode);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- seekBar.getThumb().setColorFilter(Color.rgb(redProgress, 0, 0), mode);
- }
- break;
- case R.id.sb_green:
- seekBar.getProgressDrawable().setColorFilter(Color.rgb(0, greenProgress, 0), mode);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- seekBar.getThumb().setColorFilter(Color.rgb(0, greenProgress, 0), mode);
- }
- break;
- case R.id.sb_blue:
- seekBar.getProgressDrawable().setColorFilter(Color.rgb(0, 0, blueProgress), mode);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- seekBar.getThumb().setColorFilter(Color.rgb(0, 0, blueProgress), mode);
- }
- break;
+ int id = seekBar.getId();
+ if (id == R.id.sb_red) {
+ seekBar.getProgressDrawable().setColorFilter(Color.rgb(redProgress, 0, 0), mode);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ seekBar.getThumb().setColorFilter(Color.rgb(redProgress, 0, 0), mode);
+ }
+ } else if (id == R.id.sb_green) {
+ seekBar.getProgressDrawable().setColorFilter(Color.rgb(0, greenProgress, 0), mode);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ seekBar.getThumb().setColorFilter(Color.rgb(0, greenProgress, 0), mode);
+ }
+ } else if (id == R.id.sb_blue) {
+ seekBar.getProgressDrawable().setColorFilter(Color.rgb(0, 0, blueProgress), mode);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ seekBar.getThumb().setColorFilter(Color.rgb(0, 0, blueProgress), mode);
+ }
}
}
};
@@ -82,13 +81,10 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
green.setOnSeekBarChangeListener(seekBarChangeListener);
blue.setOnSeekBarChangeListener(seekBarChangeListener);
- selectColor.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onColorSelectedListener.onColorChosen(ColorPickerDialogFragment.this,
- red.getProgress(), green.getProgress(), blue.getProgress());
- dismiss();
- }
+ selectColor.setOnClickListener(v -> {
+ onColorSelectedListener.onColorChosen(ColorPickerDialogFragment.this,
+ red.getProgress(), green.getProgress(), blue.getProgress());
+ dismiss();
});
return rootView;
diff --git a/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/MainActivity.java b/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/MainActivity.java
index 84f7c97..8ec7548 100644
--- a/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/MainActivity.java
+++ b/example/src/main/java/antonkozyriatskyi/circularprogressindicatorexample/MainActivity.java
@@ -2,18 +2,18 @@
import android.graphics.Color;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
-import android.widget.Switch;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SwitchCompat;
import java.util.ArrayList;
import java.util.HashMap;
@@ -26,6 +26,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private Button dotColor;
private SeekBar dotWidth;
+ private SeekBar gapSize;
private CircularProgressIndicator circularProgress;
@@ -52,66 +53,44 @@ protected void onCreate(Bundle savedInstanceState) {
final SeekBar progressBackgroundStrokeWidth = findViewById(R.id.sb_progress_background_width);
SeekBar textSize = findViewById(R.id.sb_text_size);
dotWidth = findViewById(R.id.sb_dot_width);
+ gapSize = findViewById(R.id.sb_gap_size);
progress.setOnSeekBarChangeListener(this);
progressStrokeWidth.setOnSeekBarChangeListener(this);
progressBackgroundStrokeWidth.setOnSeekBarChangeListener(this);
textSize.setOnSeekBarChangeListener(this);
dotWidth.setOnSeekBarChangeListener(this);
+ gapSize.setOnSeekBarChangeListener(this);
CheckBox drawDot = findViewById(R.id.cb_draw_dot);
- drawDot.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- circularProgress.setShouldDrawDot(isChecked);
- dotWidth.setEnabled(isChecked);
- dotColor.setEnabled(isChecked);
- }
+ drawDot.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ circularProgress.setShouldDrawDot(isChecked);
+ dotWidth.setEnabled(isChecked);
+ dotColor.setEnabled(isChecked);
});
CheckBox useCustomTextAdapter = findViewById(R.id.cb_custom_text_adapter);
- useCustomTextAdapter.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- circularProgress.setProgressTextAdapter(isChecked ? TIME_TEXT_ADAPTER : null);
- }
- });
+ useCustomTextAdapter.setOnCheckedChangeListener((buttonView, isChecked) -> circularProgress.setProgressTextAdapter(isChecked ? TIME_TEXT_ADAPTER : null));
CheckBox fillBackground = findViewById(R.id.cb_fill_background);
- fillBackground.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- circularProgress.setFillBackgroundEnabled(isChecked);
- }
- });
+ fillBackground.setChecked(circularProgress.isFillBackgroundEnabled());
+ fillBackground.setOnCheckedChangeListener((buttonView, isChecked) -> circularProgress.setFillBackgroundEnabled(isChecked));
+
+ CheckBox showText = findViewById(R.id.cb_show_text);
+ showText.setChecked(circularProgress.isShowTextEnabled());
+ showText.setOnCheckedChangeListener((buttonView, isChecked) -> circularProgress.setShowTextEnabled(isChecked));
RadioGroup progressCap = findViewById(R.id.rg_cap);
- progressCap.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- switch (checkedId) {
- case R.id.rb_cap_butt:
- circularProgress.setProgressStrokeCap(CircularProgressIndicator.CAP_BUTT);
- break;
- case R.id.rb_cap_round:
- circularProgress.setProgressStrokeCap(CircularProgressIndicator.CAP_ROUND);
- break;
- }
+ progressCap.setOnCheckedChangeListener((group, checkedId) -> {
+ if (checkedId == R.id.rb_cap_butt) {
+ circularProgress.setProgressStrokeCap(CircularProgressIndicator.CAP_BUTT);
+ } else if (checkedId == R.id.rb_cap_round) {
+ circularProgress.setProgressStrokeCap(CircularProgressIndicator.CAP_ROUND);
}
});
- circularProgress.setOnProgressChangeListener(new CircularProgressIndicator.OnProgressChangeListener() {
- @Override
- public void onProgressChanged(double progress, double maxProgress) {
- Log.d("PROGRESS", String.format("Current: %1$.0f, max: %2$.0f", progress, maxProgress));
- }
- });
+ circularProgress.setOnProgressChangeListener((progress1, maxProgress) -> Log.d("PROGRESS", String.format("Current: %1$.0f, max: %2$.0f", progress1, maxProgress)));
- Switch animationSwitch = findViewById(R.id.sw_enable_animation);
- animationSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- circularProgress.setAnimationEnabled(isChecked);
- }
- });
+ SwitchCompat animationSwitch = findViewById(R.id.sw_enable_animation);
+ animationSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> circularProgress.setAnimationEnabled(isChecked));
Spinner gradientType = findViewById(R.id.sp_gradient_type);
@@ -136,7 +115,6 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
gradient.put("value", "3");
gradients.add(gradient);
-
gradientType.setAdapter(
new SimpleAdapter(
this,
@@ -163,19 +141,15 @@ public void onClick(View v) {
ColorPickerDialogFragment dialog = new ColorPickerDialogFragment();
dialog.setOnColorSelectedListener(this);
String tag = null;
- switch (v.getId()) {
- case R.id.btn_progress_color:
- tag = "progressColor";
- break;
- case R.id.btn_background_color:
- tag = "progressBackgroundColor";
- break;
- case R.id.btn_text_color:
- tag = "textColor";
- break;
- case R.id.btn_dot_color:
- tag = "dotColor";
- break;
+ int id = v.getId();
+ if (id == R.id.btn_progress_color) {
+ tag = "progressColor";
+ } else if (id == R.id.btn_background_color) {
+ tag = "progressBackgroundColor";
+ } else if (id == R.id.btn_text_color) {
+ tag = "textColor";
+ } else if (id == R.id.btn_dot_color) {
+ tag = "dotColor";
}
dialog.show(getSupportFragmentManager(), tag);
@@ -183,22 +157,19 @@ public void onClick(View v) {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- switch (seekBar.getId()) {
- case R.id.sb_progress:
- circularProgress.setCurrentProgress(progress);
- break;
- case R.id.sb_progress_width:
- circularProgress.setProgressStrokeWidthDp(progress);
- break;
- case R.id.sb_dot_width:
- circularProgress.setDotWidthDp(progress);
- break;
- case R.id.sb_text_size:
- circularProgress.setTextSizeSp(progress);
- break;
- case R.id.sb_progress_background_width:
- circularProgress.setProgressBackgroundStrokeWidthDp(progress);
- break;
+ int id = seekBar.getId();
+ if (id == R.id.sb_progress) {
+ circularProgress.setCurrentProgress(progress);
+ } else if (id == R.id.sb_progress_width) {
+ circularProgress.setProgressStrokeWidthDp(progress);
+ } else if (id == R.id.sb_dot_width) {
+ circularProgress.setDotWidthDp(progress);
+ } else if (id == R.id.sb_text_size) {
+ circularProgress.setTextSizeSp(progress);
+ } else if (id == R.id.sb_progress_background_width) {
+ circularProgress.setProgressBackgroundStrokeWidthDp(progress);
+ } else if (id == R.id.sb_gap_size) {
+ circularProgress.setProgressGap(progress * 10);
}
}
@@ -233,27 +204,24 @@ public void onColorChosen(ColorPickerDialogFragment dialog, int r, int g, int b)
}
}
- private static final CircularProgressIndicator.ProgressTextAdapter TIME_TEXT_ADAPTER = new CircularProgressIndicator.ProgressTextAdapter() {
- @Override
- public String formatText(double time) {
- int hours = (int) (time / 3600);
- time %= 3600;
- int minutes = (int) (time / 60);
- int seconds = (int) (time % 60);
- StringBuilder sb = new StringBuilder();
- if (hours < 10) {
- sb.append(0);
- }
- sb.append(hours).append(":");
- if (minutes < 10) {
- sb.append(0);
- }
- sb.append(minutes).append(":");
- if (seconds < 10) {
- sb.append(0);
- }
- sb.append(seconds);
- return sb.toString();
+ private static final CircularProgressIndicator.ProgressTextAdapter TIME_TEXT_ADAPTER = time -> {
+ int hours = (int) (time / 3600);
+ time %= 3600;
+ int minutes = (int) (time / 60);
+ int seconds = (int) (time % 60);
+ StringBuilder sb = new StringBuilder();
+ if (hours < 10) {
+ sb.append(0);
+ }
+ sb.append(hours).append(":");
+ if (minutes < 10) {
+ sb.append(0);
+ }
+ sb.append(minutes).append(":");
+ if (seconds < 10) {
+ sb.append(0);
}
+ sb.append(seconds);
+ return sb.toString();
};
}
diff --git a/example/src/main/res/layout/activity_main.xml b/example/src/main/res/layout/activity_main.xml
index e050f43..004dd00 100644
--- a/example/src/main/res/layout/activity_main.xml
+++ b/example/src/main/res/layout/activity_main.xml
@@ -5,15 +5,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- tools:context="antonkozyriatskyi.circularprogressindicatorexample.MainActivity">
+ tools:context="antonkozyriatskyi.circularprogressindicatorexample.MainActivity"
+ tools:ignore="HardcodedText">
-
@@ -101,6 +102,7 @@
android:id="@+id/cb_custom_text_adapter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="Use custom text adapter (HH:MM:SS)" />
@@ -108,9 +110,18 @@
android:id="@+id/cb_fill_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="Fill background" />
+
+
+
+
+
+
-
+ android:layout_height="wrap_content" />