Skip to content

Commit 6fd920a

Browse files
committed
[ProgressIndicator] Added ActiveIndicator to improve readability.
- Removed unnecessary access modifiers. - Removed unnecessary doc comments. PiperOrigin-RevId: 597062929
1 parent 7e9318e commit 6fd920a

9 files changed

+142
-154
lines changed

lib/java/com/google/android/material/progressindicator/CircularDrawingDelegate.java

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import android.graphics.Paint.Style;
2626
import android.graphics.Rect;
2727
import android.graphics.RectF;
28-
import androidx.annotation.ColorInt;
2928
import androidx.annotation.FloatRange;
3029
import androidx.annotation.IntRange;
3130
import androidx.annotation.NonNull;
@@ -47,17 +46,17 @@ final class CircularDrawingDelegate extends DrawingDelegate<CircularProgressIndi
4746
private float totalTrackLengthFraction;
4847

4948
/** Instantiates CircularDrawingDelegate with the current spec. */
50-
public CircularDrawingDelegate(@NonNull CircularProgressIndicatorSpec spec) {
49+
CircularDrawingDelegate(@NonNull CircularProgressIndicatorSpec spec) {
5150
super(spec);
5251
}
5352

5453
@Override
55-
public int getPreferredWidth() {
54+
int getPreferredWidth() {
5655
return getSize();
5756
}
5857

5958
@Override
60-
public int getPreferredHeight() {
59+
int getPreferredHeight() {
6160
return getSize();
6261
}
6362

@@ -75,7 +74,7 @@ public int getPreferredHeight() {
7574
* @param isHiding Whether the drawable is currently animating to hide
7675
*/
7776
@Override
78-
public void adjustCanvas(
77+
void adjustCanvas(
7978
@NonNull Canvas canvas,
8079
@NonNull Rect bounds,
8180
@FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction,
@@ -130,31 +129,19 @@ public void adjustCanvas(
130129
}
131130
}
132131

133-
/**
134-
* Fills a part of the track with the designated indicator color. The filling part is defined with
135-
* two fractions normalized to [0, 1] representing the start degree and the end degree from 0 deg
136-
* (top). If start fraction is larger than the end fraction, it will draw the arc across 0 deg.
137-
*
138-
* @param canvas Canvas to draw.
139-
* @param paint Paint used to draw.
140-
* @param startFraction A fraction representing where to start the drawing along the track.
141-
* @param endFraction A fraction representing where to end the drawing along the track.
142-
* @param color The color used to draw the indicator.
143-
* @param drawableAlpha The alpha [0, 255] from the caller drawable.
144-
*/
145132
@Override
146133
void fillIndicator(
147134
@NonNull Canvas canvas,
148135
@NonNull Paint paint,
149-
@FloatRange(from = 0.0, to = 1.0) float startFraction,
150-
@FloatRange(from = 0.0, to = 1.0) float endFraction,
151-
@ColorInt int color,
136+
@NonNull ActiveIndicator activeIndicator,
152137
@IntRange(from = 0, to = 255) int drawableAlpha) {
138+
float startFraction = activeIndicator.startFraction;
139+
float endFraction = activeIndicator.endFraction;
153140
// No need to draw if startFraction and endFraction are same.
154141
if (startFraction == endFraction) {
155142
return;
156143
}
157-
color = MaterialColors.compositeARGBWithAlpha(color, drawableAlpha);
144+
int color = MaterialColors.compositeARGBWithAlpha(activeIndicator.color, drawableAlpha);
158145

159146
// Sets up the paint.
160147
paint.setStyle(Style.STROKE);
@@ -170,8 +157,16 @@ void fillIndicator(
170157
startFraction %= 1;
171158
if (totalTrackLengthFraction < 1 && startFraction + arcFraction > 1) {
172159
// Breaks the arc at 0 degree for ESCAPE animation.
173-
fillIndicator(canvas, paint, startFraction, 1, color, drawableAlpha);
174-
fillIndicator(canvas, paint, 1, startFraction + arcFraction, color, drawableAlpha);
160+
ActiveIndicator firstPart = new ActiveIndicator();
161+
firstPart.startFraction = startFraction;
162+
firstPart.endFraction = 1f;
163+
firstPart.color = color;
164+
fillIndicator(canvas, paint, firstPart, drawableAlpha);
165+
ActiveIndicator secondPart = new ActiveIndicator();
166+
secondPart.startFraction = 1f;
167+
secondPart.endFraction = startFraction + arcFraction;
168+
secondPart.color = color;
169+
fillIndicator(canvas, paint, secondPart, drawableAlpha);
175170
return;
176171
}
177172
// Scale start and arc fraction for ESCAPE animation.
@@ -206,13 +201,6 @@ void fillIndicator(
206201
}
207202
}
208203

209-
/**
210-
* Fills the whole track with track color.
211-
*
212-
* @param canvas Canvas to draw.
213-
* @param paint Paint used to draw.
214-
* @param drawableAlpha The alpha [0, 255] from the caller drawable.
215-
*/
216204
@Override
217205
void fillTrack(
218206
@NonNull Canvas canvas,

lib/java/com/google/android/material/progressindicator/CircularIndeterminateAnimatorDelegate.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
2626
import androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback;
2727
import com.google.android.material.animation.ArgbEvaluatorCompat;
28+
import com.google.android.material.progressindicator.DrawingDelegate.ActiveIndicator;
2829

2930
/**
3031
* This is the implementation class for drawing progress indicator in the circular indeterminate
@@ -63,7 +64,7 @@ final class CircularIndeterminateAnimatorDelegate
6364
AnimationCallback animatorCompleteCallback = null;
6465

6566
public CircularIndeterminateAnimatorDelegate(@NonNull CircularProgressIndicatorSpec spec) {
66-
super(/*segmentCount=*/ 1);
67+
super(/* indicatorCount= */ 1);
6768

6869
baseSpec = spec;
6970

@@ -156,26 +157,31 @@ public void unregisterAnimatorsCompleteCallback() {
156157

157158
/** Updates the segment position array based on current playtime. */
158159
private void updateSegmentPositions(int playtime) {
160+
ActiveIndicator activeIndicator = activeIndicators.get(0);
159161
// Adds constant rotation to segment positions.
160-
segmentPositions[0] = CONSTANT_ROTATION_DEGREES * animationFraction + TAIL_DEGREES_OFFSET;
161-
segmentPositions[1] = CONSTANT_ROTATION_DEGREES * animationFraction;
162+
activeIndicator.startFraction =
163+
CONSTANT_ROTATION_DEGREES * animationFraction + TAIL_DEGREES_OFFSET;
164+
activeIndicator.endFraction = CONSTANT_ROTATION_DEGREES * animationFraction;
162165
// Adds cycle specific rotation to segment positions.
163166
for (int cycleIndex = 0; cycleIndex < TOTAL_CYCLES; cycleIndex++) {
164167
// While expanding.
165168
float fraction =
166169
getFractionInRange(playtime, DELAY_TO_EXPAND_IN_MS[cycleIndex], DURATION_TO_EXPAND_IN_MS);
167-
segmentPositions[1] += interpolator.getInterpolation(fraction) * EXTRA_DEGREES_PER_CYCLE;
170+
activeIndicator.endFraction +=
171+
interpolator.getInterpolation(fraction) * EXTRA_DEGREES_PER_CYCLE;
168172
// While collapsing.
169173
fraction =
170174
getFractionInRange(
171175
playtime, DELAY_TO_COLLAPSE_IN_MS[cycleIndex], DURATION_TO_COLLAPSE_IN_MS);
172-
segmentPositions[0] += interpolator.getInterpolation(fraction) * EXTRA_DEGREES_PER_CYCLE;
176+
activeIndicator.startFraction +=
177+
interpolator.getInterpolation(fraction) * EXTRA_DEGREES_PER_CYCLE;
173178
}
174179
// Closes the gap between head and tail for complete end.
175-
segmentPositions[0] += (segmentPositions[1] - segmentPositions[0]) * completeEndFraction;
180+
activeIndicator.startFraction +=
181+
(activeIndicator.endFraction - activeIndicator.startFraction) * completeEndFraction;
176182

177-
segmentPositions[0] /= 360;
178-
segmentPositions[1] /= 360;
183+
activeIndicator.startFraction = activeIndicator.startFraction / 360f;
184+
activeIndicator.endFraction = activeIndicator.endFraction / 360f;
179185
}
180186

181187
/** Updates the segment color array based on current playtime. */
@@ -190,7 +196,7 @@ private void maybeUpdateSegmentColors(int playtime) {
190196
int startColor = baseSpec.indicatorColors[startColorIndex];
191197
int endColor = baseSpec.indicatorColors[endColorIndex];
192198
float colorFraction = interpolator.getInterpolation(timeFraction);
193-
segmentColors[0] =
199+
activeIndicators.get(0).color =
194200
ArgbEvaluatorCompat.getInstance().evaluate(colorFraction, startColor, endColor);
195201
break;
196202
}
@@ -200,7 +206,7 @@ private void maybeUpdateSegmentColors(int playtime) {
200206
@VisibleForTesting
201207
void resetPropertiesForNewStart() {
202208
indicatorColorIndexOffset = 0;
203-
segmentColors[0] = baseSpec.indicatorColors[0];
209+
activeIndicators.get(0).color = baseSpec.indicatorColors[0];
204210
completeEndFraction = 0f;
205211
}
206212

lib/java/com/google/android/material/progressindicator/DeterminateDrawable.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
import android.content.Context;
2020
import android.graphics.Canvas;
21-
import android.graphics.Color;
2221
import android.graphics.Rect;
2322
import android.widget.ProgressBar;
2423
import androidx.annotation.NonNull;
2524
import androidx.dynamicanimation.animation.DynamicAnimation;
2625
import androidx.dynamicanimation.animation.FloatPropertyCompat;
2726
import androidx.dynamicanimation.animation.SpringAnimation;
2827
import androidx.dynamicanimation.animation.SpringForce;
28+
import com.google.android.material.progressindicator.DrawingDelegate.ActiveIndicator;
2929

3030
/** This class draws the graphics for determinate mode. */
3131
public final class DeterminateDrawable<S extends BaseProgressIndicatorSpec>
@@ -41,8 +41,9 @@ public final class DeterminateDrawable<S extends BaseProgressIndicatorSpec>
4141
// Animation.
4242
private final SpringForce springForce;
4343
private final SpringAnimation springAnimation;
44-
// Fraction of displayed indicator in the total width.
45-
private float indicatorFraction;
44+
// Active indicator for the progress.
45+
private final ActiveIndicator activeIndicator;
46+
private final ActiveIndicator partialTrack;
4647
// Whether to skip the spring animation on level change event.
4748
private boolean skipAnimationOnLevelChange = false;
4849

@@ -53,6 +54,9 @@ public final class DeterminateDrawable<S extends BaseProgressIndicatorSpec>
5354
super(context, baseSpec);
5455

5556
setDrawingDelegate(drawingDelegate);
57+
activeIndicator = new ActiveIndicator();
58+
partialTrack = new ActiveIndicator();
59+
partialTrack.endFraction = 1f;
5660

5761
springForce = new SpringForce();
5862

@@ -230,40 +234,36 @@ public void draw(@NonNull Canvas canvas) {
230234
drawingDelegate.validateSpecAndAdjustCanvas(
231235
canvas, getBounds(), getGrowFraction(), isShowing(), isHiding());
232236

233-
int indicatorColor = baseSpec.indicatorColors[0];
237+
activeIndicator.color = baseSpec.indicatorColors[0];
234238
if (baseSpec.indicatorTrackGapSize > 0) {
235-
int trackColor = baseSpec.trackColor;
239+
partialTrack.color = baseSpec.trackColor;
236240
// Draws the full transparent track.
237-
baseSpec.trackColor = Color.TRANSPARENT;
238-
drawingDelegate.fillTrack(canvas, paint, getAlpha());
239-
baseSpec.trackColor = trackColor;
241+
drawingDelegate.fillTrack(canvas, paint, /* drawableAlpha= */ 0);
240242
// Draws the indicator and track.
241243
int gapSize = baseSpec.indicatorTrackGapSize;
242244
// TODO: workaround to maintain pixel-perfect compatibility with drawing logic
243245
// not using indicatorTrackGapSize.
244246
// See https://github.com/material-components/material-components-android/commit/0ce6ae4.
245247
baseSpec.indicatorTrackGapSize = 0;
246-
drawingDelegate.fillIndicator(
247-
canvas, paint, 0f, getIndicatorFraction(), indicatorColor, getAlpha());
248+
drawingDelegate.fillIndicator(canvas, paint, activeIndicator, getAlpha());
248249
baseSpec.indicatorTrackGapSize = gapSize;
249-
drawingDelegate.fillIndicator(
250-
canvas, paint, getIndicatorFraction(), 1f, trackColor, getAlpha());
250+
drawingDelegate.fillIndicator(canvas, paint, partialTrack, getAlpha());
251251
} else {
252252
drawingDelegate.fillTrack(canvas, paint, getAlpha());
253-
drawingDelegate.fillIndicator(
254-
canvas, paint, 0f, getIndicatorFraction(), indicatorColor, getAlpha());
253+
drawingDelegate.fillIndicator(canvas, paint, activeIndicator, getAlpha());
255254
}
256255
canvas.restore();
257256
}
258257

259258
// ******************* Getters and setters *******************
260259

261260
private float getIndicatorFraction() {
262-
return indicatorFraction;
261+
return activeIndicator.endFraction;
263262
}
264263

265264
private void setIndicatorFraction(float indicatorFraction) {
266-
this.indicatorFraction = indicatorFraction;
265+
activeIndicator.endFraction = indicatorFraction;
266+
partialTrack.startFraction = indicatorFraction;
267267
invalidateSelf();
268268
}
269269

lib/java/com/google/android/material/progressindicator/DrawingDelegate.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,17 @@ abstract void adjustCanvas(
6464
boolean isHiding);
6565

6666
/**
67-
* Fills a part of the track with the designated indicator color. The filling part is defined with
68-
* two fractions normalized to [0, 1] representing the start and the end of the track.
67+
* Fills a part of the track as an active indicator.
6968
*
7069
* @param canvas Canvas to draw.
7170
* @param paint Paint used to draw.
72-
* @param startFraction A fraction representing where to start the drawing along the track.
73-
* @param endFraction A fraction representing where to end the drawing along the track.
74-
* @param color The color used to draw the indicator.
71+
* @param activeIndicator The ActiveIndicator object of the current active indicator being drawn.
7572
* @param drawableAlpha The alpha [0, 255] from the caller drawable.
7673
*/
7774
abstract void fillIndicator(
7875
@NonNull Canvas canvas,
7976
@NonNull Paint paint,
80-
@FloatRange(from = 0.0, to = 1.0) float startFraction,
81-
@FloatRange(from = 0.0, to = 1.0) float endFraction,
82-
@ColorInt int color,
77+
@NonNull ActiveIndicator activeIndicator,
8378
@IntRange(from = 0, to = 255) int drawableAlpha);
8479

8580
/**
@@ -103,4 +98,17 @@ void validateSpecAndAdjustCanvas(
10398
spec.validateSpec();
10499
adjustCanvas(canvas, bounds, trackThicknessFraction, isShowing, isHiding);
105100
}
101+
102+
protected static class ActiveIndicator {
103+
// The fraction [0, 1] of the start position on the full track.
104+
@FloatRange(from = 0.0, to = 1.0)
105+
float startFraction;
106+
107+
// The fraction [0, 1] of the end position on the full track.
108+
@FloatRange(from = 0.0, to = 1.0)
109+
float endFraction;
110+
111+
// The color of the indicator without applying the drawable's alpha.
112+
@ColorInt int color;
113+
}
106114
}

lib/java/com/google/android/material/progressindicator/IndeterminateAnimatorDelegate.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,27 @@
2020
import android.graphics.drawable.Drawable;
2121
import androidx.annotation.NonNull;
2222
import androidx.vectordrawable.graphics.drawable.Animatable2Compat.AnimationCallback;
23+
import com.google.android.material.progressindicator.DrawingDelegate.ActiveIndicator;
24+
import java.util.ArrayList;
25+
import java.util.List;
2326

2427
/** A delegate abstract class for animating properties used in drawing the graphics. */
2528
abstract class IndeterminateAnimatorDelegate<T extends Animator> {
2629

2730
// The drawable associated with this delegate.
2831
protected IndeterminateDrawable drawable;
29-
// A float array of numbers in [0, 1] representing the positions of ends of each segment on the
30-
// track.
31-
protected final float[] segmentPositions;
32-
// An integer array of displayed colors used for each indicator segment defined by every two
33-
// segment positions.
34-
protected final int[] segmentColors;
32+
33+
protected final List<ActiveIndicator> activeIndicators;
3534

3635
/**
3736
* This constructor should be overridden with other necessary actions, e.g. instantiating the
3837
* animator.
3938
*/
40-
protected IndeterminateAnimatorDelegate(int segmentCount) {
41-
this.segmentPositions = new float[segmentCount * 2];
42-
this.segmentColors = new int[segmentCount];
39+
protected IndeterminateAnimatorDelegate(int indicatorCount) {
40+
activeIndicators = new ArrayList<>();
41+
for (int i = 0; i < indicatorCount; i++) {
42+
activeIndicators.add(new ActiveIndicator());
43+
}
4344
}
4445

4546
/** Registers the drawable associated to this delegate. */
@@ -62,7 +63,7 @@ protected float getFractionInRange(int playtime, int start, int duration) {
6263

6364
/**
6465
* Invalidates the spec values used by the animator delegate. When the spec values are changed in
65-
* indicator class, values assigned to animators or segments don't get updated until they are
66+
* indicator class, values assigned to animators or indicators don't get updated until they are
6667
* explicitly reset. Call this to apply the changes immediately.
6768
*/
6869
public abstract void invalidateSpecValues();

0 commit comments

Comments
 (0)