Skip to content

Commit

Permalink
[ProgressIndicator] Added support of rounded corners.
Browse files Browse the repository at this point in the history
- Added attribute cornerRadius.
- Added rounded corner support for linear determinate and indeterminate (non-seamless) mode.
- Added rounded corner support for circular determinate and indeterminate mode.
- Added screenshot tests.
- Modified show cases in Catalog to demo this feature.

PiperOrigin-RevId: 316400672
  • Loading branch information
pekingme authored and melaniegoetz committed Jun 16, 2020
1 parent 584d725 commit 48c4ef0
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cat_progress_indicator_inverse_linear_bidirectional_grow_single_color"/>
android:text="@string/cat_progress_indicator_rounded_inverse_linear_bidirectional_grow_single_color"/>
<com.google.android.material.progressindicator.ProgressIndicator
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"
app:indicatorColor="?attr/colorPrimary"
app:growMode="bidirectional"
app:inverse="true" />
app:inverse="true"
app:indicatorCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"/>

<TextView
android:layout_width="wrap_content"
Expand Down Expand Up @@ -103,15 +104,16 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cat_progress_indicator_inverse_circular_bidirectional_grow_single_color"/>
android:text="@string/cat_progress_indicator_rounded_inverse_circular_bidirectional_grow_single_color"/>
<com.google.android.material.progressindicator.ProgressIndicator
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Determinate"
app:indicatorColor="?attr/colorPrimary"
app:inverse="true"
app:growMode="bidirectional"/>
app:growMode="bidirectional"
app:indicatorCornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"/>
</LinearLayout>

<LinearLayout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cat_progress_indicator_inverse_linear_bidirectional_grow_single_color"/>
android:text="@string/cat_progress_indicator_rounded_inverse_linear_bidirectional_grow_single_color"/>
<com.google.android.material.progressindicator.ProgressIndicator
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
app:indicatorColor="?attr/colorPrimary"
app:inverse="true"
app:growMode="bidirectional"/>
app:growMode="bidirectional"
app:cornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"/>

<TextView
android:layout_width="wrap_content"
Expand Down Expand Up @@ -98,14 +99,15 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cat_progress_indicator_inverse_circular_bidirectional_grow_single_color"/>
android:text="@string/cat_progress_indicator_rounded_inverse_circular_bidirectional_grow_single_color"/>
<com.google.android.material.progressindicator.ProgressIndicator
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate"
app:indicatorColor="?attr/colorPrimary"
app:inverse="true"
app:growMode="bidirectional"/>
app:growMode="bidirectional"
app:cornerRadius="@dimen/mtrl_progress_indicator_full_rounded_corner_radius"/>
</LinearLayout>

<LinearLayout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,17 @@
description="A linear progress indicator with no grow and a single color [CHAR LIMIT=NONE]">
Single color linear with no grow
</string>
<string name="cat_progress_indicator_inverse_linear_bidirectional_grow_single_color"
description="An inverse linear progress indicator with bidirectional grow and a single color [CHAR LIMIT=NONE]">
Single color inverse linear with bidirectional grow
<string name="cat_progress_indicator_rounded_inverse_linear_bidirectional_grow_single_color"
description="An inverse linear progress indicator with bidirectional grow, rounded corners and a single color [CHAR LIMIT=NONE]">
Single color inverse linear with bidirectional grow and rounded corners
</string>
<string name="cat_progress_indicator_linear_incoming_grow_multiple_colors"
description="A linear progress indicator with incoming grow and multiple colors [CHAR LIMIT=NONE]">
Multiple color linear with incoming grow
</string>
<string name="cat_progress_indicator_linear_outgoing_grow_multiple_colors"
description="A linear progress indicator with outgoing grow and multiple colors [CHAR LIMIT=NONE]">
Linear with outgoing grow, when multiple colors are defined.
Linear with outgoing grow, when multiple colors are defined
</string>
<string name="cat_progress_indicator_linear_outgoing_grow_multiple_seamless_colors"
description="A linear progress indicator with outgoing grow and multiple seeamless colors [CHAR LIMIT=NONE]">
Expand All @@ -103,9 +103,9 @@
description="A circular progress indicator with no grow and a single color [CHAR LIMIT=NONE]">
Single color circular with no grow
</string>
<string name="cat_progress_indicator_inverse_circular_bidirectional_grow_single_color"
description="An inverse circular progress indicator with bidirectional grow and a single color [CHAR LIMIT=NONE]">
Single color inverse circular with bidirectional grow
<string name="cat_progress_indicator_rounded_inverse_circular_bidirectional_grow_single_color"
description="An inverse circular progress indicator with bidirectional grow, rounded corners and a single color [CHAR LIMIT=NONE]">
Single color inverse circular with bidirectional grow and rounded corners
</string>
<string name="cat_progress_indicator_circular_incoming_grow_multiple_colors"
description="A circular progress indicator with incoming grow and multiple colors [CHAR LIMIT=NONE]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;

Expand All @@ -31,10 +32,10 @@ final class CircularDrawingDelegate implements DrawingDelegate {
private int arcInverseFactor = 1;

/**
* Adjusts the canvas for drawing circular progress indicator. It flips the canvas along x axis if
* inverse, and rotates the canvas -90 degrees to keep the 0 at the top. The canvas is clipped to
* a square with the size just includes the inset. It will also pre-calculate the bound for
* drawing the arc based on the indicate radius and current indicator width.
* Adjusts the canvas for drawing circular progress indicator. It rotates the canvas -90 degrees
* to keep the 0 at the top. The canvas is clipped to a square with the size just includes the
* inset. It will also pre-calculate the bound for drawing the arc based on the indicate radius
* and current indicator width.
*
* @param canvas Canvas to draw.
* @param progressIndicator The component currently serving.
Expand Down Expand Up @@ -86,27 +87,79 @@ public void adjustCanvas(
* @param color The filled color.
* @param startFraction A fraction representing where to start the drawing along the track.
* @param endFraction A fraction representing where to end the drawing along the track.
* @param trackWidth The actual width of the track to fill in.
* @param trackWidth The width of the track in px.
* @param cornerRadius The radius of corners in px, if rounded corners are applied.
*/
@Override
public void fillTrackWithColor(
@NonNull Canvas canvas,
@NonNull Paint paint,
int color,
@ColorInt int color,
@FloatRange(from = 0.0, to = 1.0) float startFraction,
@FloatRange(from = 0.0, to = 1.0) float endFraction,
float trackWidth) {
float trackWidth,
float cornerRadius) {
// No need to draw if startFraction and endFraction are same.
if (startFraction == endFraction) {
return;
}

// Initializes Paint object.
paint.setStyle(Style.STROKE);
paint.setStrokeCap(Cap.BUTT);
paint.setAntiAlias(true);
paint.setColor(color);
paint.setStrokeWidth(trackWidth);

// Draws the stroke arc without rounded corners.
float startDegree = startFraction * 360 * arcInverseFactor;
float arcDegree =
endFraction >= startFraction
? (endFraction - startFraction) * 360 * arcInverseFactor
: (1 + endFraction - startFraction) * 360 * arcInverseFactor;
canvas.drawArc(arcBound, startDegree, arcDegree, false, paint);

// Draws rounded corners if needed.
if (cornerRadius > 0 && Math.abs(arcDegree) < 360) {
paint.setStyle(Style.FILL);
RectF cornerPatternRectBound =
new RectF(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius);
drawRoundedEnd(
canvas, paint, trackWidth, cornerRadius, startDegree, true, cornerPatternRectBound);
drawRoundedEnd(
canvas,
paint,
trackWidth,
cornerRadius,
startDegree + arcDegree,
false,
cornerPatternRectBound);
}
}

private void drawRoundedEnd(
Canvas canvas,
Paint paint,
float trackWidth,
float cornerRadius,
float positionInDeg,
boolean isStartPosition,
RectF cornerPatternRectBound) {
float startOrEndFactor = isStartPosition ? -1 : 1;
canvas.save();
canvas.rotate(positionInDeg);
canvas.drawRect(
arcBound.right - trackWidth / 2 + cornerRadius,
Math.min(0, startOrEndFactor * cornerRadius * arcInverseFactor),
arcBound.right + trackWidth / 2 - cornerRadius,
Math.max(0, startOrEndFactor * cornerRadius * arcInverseFactor),
paint);
canvas.translate(arcBound.right - trackWidth / 2 + cornerRadius, 0);
canvas.drawArc(
cornerPatternRectBound, 180, -startOrEndFactor * 90 * arcInverseFactor, true, paint);
canvas.translate(trackWidth - 2 * cornerRadius, 0);
canvas.drawArc(
cornerPatternRectBound, 0, startOrEndFactor * 90 * arcInverseFactor, true, paint);
canvas.restore();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,18 @@ public void draw(@NonNull Canvas canvas) {
drawingDelegate.adjustCanvas(canvas, progressIndicator, getGrowFraction());

float displayedIndicatorWidth = progressIndicator.getIndicatorWidth() * getGrowFraction();
float displayedRoundedCornerRadius =
progressIndicator.getIndicatorCornerRadius() * getGrowFraction();

// Draws the track.
drawingDelegate.fillTrackWithColor(
canvas, paint, combinedTrackColor, 0f, 1f, displayedIndicatorWidth);
canvas,
paint,
combinedTrackColor,
0f,
1f,
displayedIndicatorWidth,
displayedRoundedCornerRadius);
// Draws the indicator.
drawingDelegate.fillTrackWithColor(
canvas,
Expand All @@ -230,7 +238,8 @@ public void draw(@NonNull Canvas canvas) {
+ getIndicatorInCycleOffset()
+ getIndicatorHeadChangeFraction() * INDICATOR_DELTA_DEGREES)
/ 360,
displayedIndicatorWidth);
displayedIndicatorWidth,
displayedRoundedCornerRadius);
canvas.restore();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,27 @@ public void draw(@NonNull Canvas canvas) {
drawingDelegate.adjustCanvas(canvas, progressIndicator, getGrowFraction());

float displayedIndicatorWidth = progressIndicator.getIndicatorWidth() * getGrowFraction();
float displayedRoundedCornerRadius =
progressIndicator.getIndicatorCornerRadius() * getGrowFraction();

// Draws the track.
drawingDelegate.fillTrackWithColor(
canvas, paint, progressIndicator.getTrackColor(), 0f, 1f, displayedIndicatorWidth);
canvas,
paint,
progressIndicator.getTrackColor(),
0f,
1f,
displayedIndicatorWidth,
displayedRoundedCornerRadius);
// Draws the indicator.
drawingDelegate.fillTrackWithColor(
canvas,
paint,
combinedIndicatorColorArray[0],
0f,
getIndicatorFraction(),
displayedIndicatorWidth);
displayedIndicatorWidth,
displayedRoundedCornerRadius);
canvas.restore();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,23 @@ void adjustCanvas(
@FloatRange(from = 0.0, to = 1.0) float widthFraction);

/**
* Fills a portion of the track with color.
* Fills a part of the track with input color. The filling part is defined with two fractions
* normalized to [0, 1] representing the start and the end of the track.
*
* @param canvas Canvas to draw.
* @param paint Paint used to draw.
* @param color The filled color.
* @param startFraction A fraction representing where to start the drawing along the track.
* @param endFraction A fraction representing where to end the drawing along the track.
* @param trackWidth The actual width of the track to fill in.
* @param trackWidth The width of the track in px.
* @param cornerRadius The radius of corners in px, if rounded corners are applied.
*/
void fillTrackWithColor(
@NonNull Canvas canvas,
@NonNull Paint paint,
@ColorInt int color,
@FloatRange(from = 0.0, to = 1.0) float startFraction,
@FloatRange(from = 0.0, to = 1.0) float endFraction,
float trackWidth);
float trackWidth,
float cornerRadius);
}

0 comments on commit 48c4ef0

Please sign in to comment.