Skip to content

Commit 0ce6ae4

Browse files
drchenhunterstich
authored andcommitted
[ProgressIndicator] Fix linear progress indicator with corner radius
When corner radius of a linear progress indicator is larger than 0, the behavior it's confusing because when the progress fraction is slightly larger than 0, the progress indicator will suddenly show with a width of twice the corner radius. Fixes this by adjusting the indicator startX and endX correctly so the visible indicator length is always proportional to the progress. Resolves #2940 PiperOrigin-RevId: 509552399
1 parent e06a119 commit 0ce6ae4

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.graphics.Canvas;
2121
import android.graphics.Paint;
2222
import android.graphics.Paint.Style;
23+
import android.graphics.Path;
2324
import android.graphics.Rect;
2425
import android.graphics.RectF;
2526
import androidx.annotation.ColorInt;
@@ -34,6 +35,7 @@ final class LinearDrawingDelegate extends DrawingDelegate<LinearProgressIndicato
3435
private float trackLength = 300f;
3536
private float displayedTrackThickness;
3637
private float displayedCornerRadius;
38+
private Path displayedTrackPath;
3739

3840
/** Instantiates LinearDrawingDelegate with the current spec. */
3941
public LinearDrawingDelegate(@NonNull LinearProgressIndicatorSpec spec) {
@@ -118,27 +120,29 @@ public void fillIndicator(
118120
return;
119121
}
120122

121-
// Horizontal position of the start adjusted based on the rounded corner radius.
122-
float adjustedStartX =
123-
-trackLength / 2 + startFraction * (trackLength - 2 * displayedCornerRadius);
124-
// Horizontal position of the end adjusted based on the rounded corner radius.
125-
float adjustedEndX =
126-
-trackLength / 2
127-
+ endFraction * (trackLength - 2 * displayedCornerRadius)
128-
+ 2 * displayedCornerRadius;
123+
float originX = -trackLength / 2;
124+
125+
// Adjusts start X and end X so when the progress indicator will start from 0 when
126+
// startFraction == 0, and always retain the specified corner radius.
127+
float adjustedStartX = originX + startFraction * trackLength - displayedCornerRadius * 2;
128+
float adjustedEndX = originX + endFraction * trackLength;
129129

130130
// Sets up the paint.
131131
paint.setStyle(Style.FILL);
132132
paint.setAntiAlias(true);
133133
paint.setColor(color);
134134

135+
canvas.save();
136+
// Avoid the indicator being drawn out of the track.
137+
canvas.clipPath(displayedTrackPath);
135138
RectF indicatorBound =
136139
new RectF(
137140
adjustedStartX,
138141
-displayedTrackThickness / 2,
139142
adjustedEndX,
140143
displayedTrackThickness / 2);
141144
canvas.drawRoundRect(indicatorBound, displayedCornerRadius, displayedCornerRadius, paint);
145+
canvas.restore();
142146
}
143147

144148
/**
@@ -156,12 +160,17 @@ void fillTrack(@NonNull Canvas canvas, @NonNull Paint paint) {
156160
paint.setAntiAlias(true);
157161
paint.setColor(trackColor);
158162

159-
RectF trackBound =
163+
displayedTrackPath = new Path();
164+
displayedTrackPath.addRoundRect(
160165
new RectF(
161166
-trackLength / 2,
162167
-displayedTrackThickness / 2,
163168
trackLength / 2,
164-
displayedTrackThickness / 2);
165-
canvas.drawRoundRect(trackBound, displayedCornerRadius, displayedCornerRadius, paint);
169+
displayedTrackThickness / 2),
170+
displayedCornerRadius,
171+
displayedCornerRadius,
172+
Path.Direction.CCW
173+
);
174+
canvas.drawPath(displayedTrackPath, paint);
166175
}
167176
}

0 commit comments

Comments
 (0)