Skip to content

Commit

Permalink
[ProgressIndicator] Updated to draw the track in Circular indetermina…
Browse files Browse the repository at this point in the history
…te mode with an option to opt out this behavior.

PiperOrigin-RevId: 629828525
  • Loading branch information
pekingme authored and leticiarossi committed May 2, 2024
1 parent 3880efe commit cb5afbc
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public final class CircularProgressIndicatorSpec extends BaseProgressIndicatorSp
/** The direction in which the indicator will rotate and grow to. */
@IndicatorDirection public int indicatorDirection;

/** Whether to show the track in the indeterminate mode. */
public boolean indeterminateTrackVisible;

/**
* Instantiates the spec for {@link CircularProgressIndicator}.
*
Expand Down Expand Up @@ -107,6 +110,8 @@ public CircularProgressIndicatorSpec(
a.getInt(
R.styleable.CircularProgressIndicator_indicatorDirectionCircular,
CircularProgressIndicator.INDICATOR_DIRECTION_CLOCKWISE);
indeterminateTrackVisible =
a.getBoolean(R.styleable.CircularProgressIndicator_indeterminateTrackVisible, true);
a.recycle();

validateSpec();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ public void draw(@NonNull Canvas canvas) {

int gapSize = baseSpec.indicatorTrackGapSize;
int trackAlpha = getAlpha();
boolean drawFullTrack = gapSize == 0 && !baseSpec.hasWavyEffect();
boolean drawTrack =
baseSpec instanceof LinearProgressIndicatorSpec
|| (baseSpec instanceof CircularProgressIndicatorSpec
&& ((CircularProgressIndicatorSpec) baseSpec).indeterminateTrackVisible);
boolean drawFullTrack = drawTrack && gapSize == 0 && !baseSpec.hasWavyEffect();

if (drawFullTrack) {
drawingDelegate.fillTrack(
Expand All @@ -214,7 +218,8 @@ public void draw(@NonNull Canvas canvas) {
baseSpec.trackColor,
trackAlpha,
/* gapSize= */ 0);
} else {
} else if (drawTrack) {
// Draws the track with partial length.
ActiveIndicator firstIndicator = animatorDelegate.activeIndicators.get(0);
ActiveIndicator lastIndicator =
animatorDelegate.activeIndicators.get(animatorDelegate.activeIndicators.size() - 1);
Expand All @@ -235,8 +240,19 @@ public void draw(@NonNull Canvas canvas) {
baseSpec.trackColor,
trackAlpha,
gapSize);
} else {
canvas.save();
canvas.rotate(lastIndicator.rotationDegree);
drawingDelegate.fillTrack(
canvas,
paint,
lastIndicator.endFraction,
firstIndicator.startFraction + 1f,
baseSpec.trackColor,
trackAlpha,
gapSize);
canvas.restore();
}
// No inactive track is drawn in circular indeterminate mode.
}

// Draws indicators and tracks in between.
Expand All @@ -249,7 +265,7 @@ public void draw(@NonNull Canvas canvas) {
drawingDelegate.fillIndicator(canvas, paint, curIndicator, getAlpha());

// Draws tracks between indicators.
if (indicatorIndex > 0 && !drawFullTrack) {
if (indicatorIndex > 0 && !drawFullTrack && drawTrack) {
ActiveIndicator prevIndicator = animatorDelegate.activeIndicators.get(indicatorIndex - 1);
drawingDelegate.fillTrack(
canvas,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,90 +18,90 @@

<declare-styleable name="BaseProgressIndicator">
<!-- Whether the progress indicator should be indeterminate mode. -->
<attr name="android:indeterminate"/>
<attr name="android:indeterminate" />
<!-- The thickness of the progress track and indicator. -->
<attr name="trackThickness" format="dimension"/>
<attr name="trackThickness" format="dimension" />
<!--
The radius of each corner of both the indicator and the track. A radius
larger than half of the track width will throw exceptions during
initialization.
-->
<attr name="trackCornerRadius" format="dimension"/>
<attr name="trackCornerRadius" format="dimension" />
<!--
The indicator color (or colors in an array). By default, it uses theme
primary color.
-->
<attr name="indicatorColor" format="color|reference"/>
<attr name="indicatorColor" format="color|reference" />
<!--
The color used for the progress track. If not defined, it will be set to
the indicatorColor and apply the android:disabledAlpha from the theme.
-->
<attr name="trackColor"/>
<attr name="trackColor" />
<!-- The animation behavior to show the indicator and track. -->
<attr name="showAnimationBehavior">
<!-- No animation used; appears immediately. -->
<enum name="none" value="0"/>
<enum name="none" value="0" />
<!--
Expands from the bottom edge to the top edge for the linear type;
expands from the inner edge to the outer edge for the circular type.
-->
<enum name="outward" value="1"/>
<enum name="outward" value="1" />
<!--
Expands from the top edge to the bottom edge for the linear type;
expands from the outer edge to the inner edge for the circular type.
-->
<enum name="inward" value="2"/>
<enum name="inward" value="2" />
</attr>
<!-- The animation behavior to hide the indicator and track. -->
<attr name="hideAnimationBehavior">
<!-- No animation used; disappears immediately. -->
<enum name="none" value="0"/>
<enum name="none" value="0" />
<!--
Collapses from the bottom edge to the top edge for the linear type;
collapses from the inner edge to the outer edge for the circular type.
-->
<enum name="outward" value="1"/>
<enum name="outward" value="1" />
<!--
Collapses from the top edge to the bottom edge for the linear type;
collapses from the outer edge to the inner edge for the circular type.
-->
<enum name="inward" value="2"/>
<enum name="inward" value="2" />
<!--
Escapes in the progression direction for the linear type;
no effect for the circular type.
-->
<enum name="escape" value="3"/>
<enum name="escape" value="3" />
</attr>
<!--
The time, in milliseconds, that the progress indicator will wait to show
once show() is called. If set to zero or negative values (-1 as default),
the show action will start immediately.
-->
<attr name="showDelay" format="integer"/>
<attr name="showDelay" format="integer" />
<!--
The minimum time, in milliseconds, that the requested hide action will
wait to start once show action is started. If set to zero or negative
values (-1 as default), the requested hide action will start immediately.
This value is capped to a limit defined in ProgressIndicator class.
-->
<attr name="minHideDelay" format="integer"/>
<attr name="minHideDelay" format="integer" />
<!--
The size of the gap between the progress indicator and track.
-->
<attr name="indicatorTrackGapSize" format="dimension"/>
<attr name="indicatorTrackGapSize" format="dimension" />
<!--
Defines the wavelength (in dp) of the wave effect.
-->
<attr name="wavelength" format="dimension"/>
<attr name="wavelength" format="dimension" />
<!--
Defines the amplitude (in dp) of the wave effect.
-->
<attr name="amplitude" format="dimension"/>
<attr name="amplitude" format="dimension" />
<!--
Defines the wave speed (in dp/s) of the wavy effect. If positive, wave moves towards 100%; if
negative, wave moves towards 0%.
-->
<attr name="speed" format="dimension"/>
<attr name="speed" format="dimension" />
</declare-styleable>

<declare-styleable name="LinearProgressIndicator">
Expand All @@ -112,55 +112,57 @@
This type is only available when there are three or more indicator
colors.
-->
<enum name="contiguous" value="0"/>
<enum name="contiguous" value="0" />
<!--
There will be two disjoint segments in the same color per cycle. The color iterates between cycles.
-->
<enum name="disjoint" value="1"/>
<enum name="disjoint" value="1" />
</attr>
<!--
The direction in which the linear indicator progresses, in the determinate
mode, and is animated, in the indeterminate mode.
-->
<attr name="indicatorDirectionLinear">
<!-- Animated from the left end to the right end of the track. -->
<enum name="leftToRight" value="0"/>
<enum name="leftToRight" value="0" />
<!-- Animated from the right end to the left end of the track. -->
<enum name="rightToLeft" value="1"/>
<enum name="rightToLeft" value="1" />
<!--
Animated from the start position to the end position of the track.
This will be same as the leftToRight for API before 17.
-->
<enum name="startToEnd" value="2"/>
<enum name="startToEnd" value="2" />
<!--
Animated from the end position to the start position of the track.
This will be same as the rightToLeft for API before 17.
-->
<enum name="endToStart" value="3"/>
<enum name="endToStart" value="3" />
</attr>
<!--
The size of the stop indicator at the end of the progress track.
-->
<attr name="trackStopIndicatorSize"/>
<attr name="trackStopIndicatorSize" />
</declare-styleable>

<declare-styleable name="CircularProgressIndicator">
<!-- Whether to show the track in the indeterminate mode. -->
<attr name="indeterminateTrackVisible" format="boolean" />
<!-- The animation style of the indeterminate mode. -->
<attr name="indeterminateAnimationTypeCircular">
<!-- The active track will grow on the end point and shrink on the start point. -->
<enum name="advance" value="0"/>
<!-- The active track will grow and shrink on the end point. -->
<enum name="retreat" value="1"/>
<!-- The indicator will grow on the end point and shrink on the start point. -->
<enum name="advance" value="0" />
<!-- The indicator track will grow and shrink on the end point. -->
<enum name="retreat" value="1" />
</attr>
<!--
Defines the size (outer diameter) of the circular progress indicator.
-->
<attr name="indicatorSize" format="dimension"/>
<attr name="indicatorSize" format="dimension" />
<!--
The extra space from the outer edge of the indicator to the edge of the
canvas.
-->
<attr name="indicatorInset" format="dimension"/>
<attr name="indicatorInset" format="dimension" />
<!--
The direction in which the circular indicator progresses, in the
determinate mode, and is animated, in the indeterminate mode.
Expand All @@ -171,18 +173,18 @@
determinate mode, the indicator will progress from the top (12 o'clock)
clockwise.
-->
<enum name="clockwise" value="0"/>
<enum name="clockwise" value="0" />
<!--
In the indeterminate mode, the spinner will spin counter-clockwise; in
the determinate mode, the indicator will progress from the top (12
o'clock) counter-clockwise.
-->
<enum name="counterclockwise" value="1"/>
<enum name="counterclockwise" value="1" />
</attr>
</declare-styleable>

<!-- Style to use for LinearProgressIndicator in this theme. -->
<attr name="linearProgressIndicatorStyle" format="reference"/>
<attr name="linearProgressIndicatorStyle" format="reference" />
<!-- Style to use for CircularProgressIndicator in this theme. -->
<attr name="circularProgressIndicatorStyle" format="reference"/>
<attr name="circularProgressIndicatorStyle" format="reference" />
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<item name="indicatorInset">@dimen/mtrl_progress_circular_inset_medium</item>
<item name="trackColor">@android:color/transparent</item>
<item name="indicatorDirectionCircular">clockwise</item>
<item name="indeterminateTrackVisible">true</item>
</style>
<style name="Widget.MaterialComponents.CircularProgressIndicator.Medium"/>
<style name="Widget.MaterialComponents.CircularProgressIndicator.Small">
Expand Down Expand Up @@ -65,9 +66,18 @@
<item name="trackCornerRadius">0dp</item>
<item name="indicatorTrackGapSize">0dp</item>
</style>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.Medium" parent="Widget.MaterialComponents.CircularProgressIndicator.Medium"/>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.Small" parent="Widget.MaterialComponents.CircularProgressIndicator.Small"/>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.ExtraSmall" parent="Widget.MaterialComponents.CircularProgressIndicator.ExtraSmall"/>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.Medium" parent="Widget.MaterialComponents.CircularProgressIndicator.Medium">
<item name="trackCornerRadius">0dp</item>
<item name="indicatorTrackGapSize">0dp</item>
</style>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.Small" parent="Widget.MaterialComponents.CircularProgressIndicator.Small">
<item name="trackCornerRadius">0dp</item>
<item name="indicatorTrackGapSize">0dp</item>
</style>
<style name="Widget.Material3.CircularProgressIndicator.Legacy.ExtraSmall" parent="Widget.MaterialComponents.CircularProgressIndicator.ExtraSmall">
<item name="trackCornerRadius">0dp</item>
<item name="indicatorTrackGapSize">0dp</item>
</style>

<!-- M3 LinearProgressIndicator style -->
<style name="Widget.Material3.LinearProgressIndicator" parent="Widget.MaterialComponents.LinearProgressIndicator">
Expand All @@ -86,6 +96,7 @@
<item name="trackColor">@macro/m3_comp_progress_indicator_track_color</item>
<item name="trackCornerRadius">2dp</item>
<item name="indicatorTrackGapSize">@dimen/m3_comp_progress_indicator_active_indicator_track_space</item>
<item name="indeterminateTrackVisible">false</item>
</style>
<style name="Widget.Material3.CircularProgressIndicator.Medium"/>
<style name="Widget.Material3.CircularProgressIndicator.Small">
Expand Down

0 comments on commit cb5afbc

Please sign in to comment.