mirror of
https://github.com/material-components/material-components-android.git
synced 2026-02-20 08:39:55 +08:00
[ProgressIndicator] Added fraction support in track corner radius.
PiperOrigin-RevId: 733576933
This commit is contained in:
parent
99ff34c0f2
commit
2e97dd672e
@ -80,7 +80,7 @@ public class ProgressIndicatorMainDemoFragment extends ProgressIndicatorDemoFrag
|
||||
Slider thicknessSlider = view.findViewById(R.id.thicknessSlider);
|
||||
thicknessSlider.addOnChangeListener(
|
||||
(slider, value, fromUser) -> {
|
||||
int newThickness = Math.round(value * pixelsInDp);
|
||||
int newThickness = (int) (value * pixelsInDp);
|
||||
if (linearIndicator.getTrackThickness() != newThickness) {
|
||||
linearIndicator.setTrackThickness(newThickness);
|
||||
}
|
||||
@ -92,7 +92,7 @@ public class ProgressIndicatorMainDemoFragment extends ProgressIndicatorDemoFrag
|
||||
Slider cornerSlider = view.findViewById(R.id.cornerSlider);
|
||||
cornerSlider.addOnChangeListener(
|
||||
(slider, value, fromUser) -> {
|
||||
int newCornerRadius = Math.round(value * pixelsInDp);
|
||||
int newCornerRadius = (int) (value * pixelsInDp);
|
||||
if (linearIndicator.getTrackCornerRadius() != newCornerRadius) {
|
||||
linearIndicator.setTrackCornerRadius(newCornerRadius);
|
||||
}
|
||||
@ -104,7 +104,7 @@ public class ProgressIndicatorMainDemoFragment extends ProgressIndicatorDemoFrag
|
||||
Slider gapSlider = view.findViewById(R.id.gapSlider);
|
||||
gapSlider.addOnChangeListener(
|
||||
(slider, value, fromUser) -> {
|
||||
int newGapSize = Math.round(value * pixelsInDp);
|
||||
int newGapSize = (int) (value * pixelsInDp);
|
||||
if (linearIndicator.getIndicatorTrackGapSize() != newGapSize) {
|
||||
linearIndicator.setIndicatorTrackGapSize(newGapSize);
|
||||
}
|
||||
@ -125,7 +125,7 @@ public class ProgressIndicatorMainDemoFragment extends ProgressIndicatorDemoFrag
|
||||
Slider linearStopIndicatorSlider = view.findViewById(R.id.linearStopIndicatorSizeSlider);
|
||||
linearStopIndicatorSlider.addOnChangeListener(
|
||||
(slider, value, fromUser) -> {
|
||||
int newStopIndicatorSize = Math.round(value * pixelsInDp);
|
||||
int newStopIndicatorSize = (int) (value * pixelsInDp);
|
||||
if (linearIndicator.getTrackStopIndicatorSize() != newStopIndicatorSize) {
|
||||
linearIndicator.setTrackStopIndicatorSize(newStopIndicatorSize);
|
||||
}
|
||||
@ -134,7 +134,7 @@ public class ProgressIndicatorMainDemoFragment extends ProgressIndicatorDemoFrag
|
||||
Slider circularSizeSlider = view.findViewById(R.id.circularSizeSlider);
|
||||
circularSizeSlider.addOnChangeListener(
|
||||
(slider, value, fromUser) -> {
|
||||
int newCornerRadius = Math.round(value * pixelsInDp);
|
||||
int newCornerRadius = (int) (value * pixelsInDp);
|
||||
if (circularIndicator.getIndicatorSize() != newCornerRadius) {
|
||||
circularIndicator.setIndicatorSize(newCornerRadius);
|
||||
}
|
||||
|
||||
@ -50,12 +50,10 @@ A determinate progress indicator can be added to a layout:
|
||||
```xml
|
||||
<!-- Linear progress indicator -->
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<!-- Circular progress indicator -->
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" /><!-- Circular progress indicator -->
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
```
|
||||
|
||||
An indeterminate progress indicator can be added:
|
||||
@ -63,21 +61,19 @@ An indeterminate progress indicator can be added:
|
||||
```xml
|
||||
<!-- Linear progress indicator -->
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
<!-- Circular progress indicator -->
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:indeterminate="true" /><!-- Circular progress indicator -->
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
1. Determinate
|
||||
2. Indeterminate
|
||||
1. Determinate
|
||||
2. Indeterminate
|
||||
|
||||
### Switching from indeterminate to determinate
|
||||
|
||||
@ -85,13 +81,13 @@ Indeterminate progress indicators can smoothly transit to determinate progress
|
||||
indicators by setting the `progress` programmatically:
|
||||
|
||||
```kt
|
||||
int progress = getLoadingProgress()
|
||||
int progress = getLoadingProgress ()
|
||||
indicator.setProgressCompat(progress, true)
|
||||
```
|
||||
|
||||
**Note:** Once indeterminate progress indicators are switched to the
|
||||
determinate mode (or initialized as determinate), they can be set back to
|
||||
indeterminate mode via calling the `setIndeterminate(true)` method.
|
||||
**Note:** Once indeterminate progress indicators are switched to the determinate
|
||||
mode (or initialized as determinate), they can be set back to indeterminate mode
|
||||
via calling the `setIndeterminate(true)` method.
|
||||
|
||||
### Making progress indicators accessible
|
||||
|
||||
@ -132,8 +128,8 @@ The modes of behaviors are:
|
||||
edge and hides the view by collapsing to the baseline (bottom edge); for the
|
||||
circular type, shows the view by expanding from the outer edge and hides the
|
||||
view by collapsing to the inner edge.
|
||||
* `escape` - for the linear type, escapes in the progression direction; for the
|
||||
circular type, no effect.
|
||||
* `escape` - for the linear type, escapes in the progression direction; for
|
||||
the circular type, no effect.
|
||||
|
||||
When the hide animation behavior is not none, the visibility of the view will be
|
||||
changed after the animation finishes. Please use `setVisibilityAfterHide` method
|
||||
@ -142,8 +138,9 @@ to set the target visibility as `Visibility.INVISIBLE` (default) or
|
||||
|
||||
### Rounded corners
|
||||
|
||||
Progress indicators can have rounded corners via `app:trackCornerRadius` or the
|
||||
`setTrackCornerRadius` method.
|
||||
Progress indicators can have rounded corners via `app:trackCornerRadius` (in dp
|
||||
or fraction) or the `setTrackCornerRadius` and `setTrackCornerRadiusFraction`
|
||||
methods.
|
||||
|
||||
### Types
|
||||
|
||||
@ -179,7 +176,8 @@ API and source code:
|
||||
|
||||
The following example shows a determinate linear progress indicator.
|
||||
|
||||
<img src="assets/progressindicator/linear_determinate.gif" alt="Determinate linear progress indicator animation: purple indicator fills up
|
||||
<img src="assets/progressindicator/linear_determinate.gif" alt="Determinate
|
||||
linear progress indicator animation: purple indicator fills up
|
||||
grey
|
||||
track" width="600"/>
|
||||
|
||||
@ -187,13 +185,13 @@ In the layout:
|
||||
|
||||
```xml
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content" />
|
||||
```
|
||||
|
||||
The following example shows an indeterminate linear progress indicator.
|
||||
|
||||
<img src="assets/progressindicator/linear_indeterminate.gif" alt="Indeterminate linear progress indicator animation: purple indicator travels
|
||||
<img src="assets/progressindicator/linear_indeterminate.gif" alt="Indeterminate
|
||||
linear progress indicator animation: purple indicator travels
|
||||
along grey
|
||||
track" width="600"/>
|
||||
|
||||
@ -201,9 +199,8 @@ In the layout:
|
||||
|
||||
```xml
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
android:layout_width="match_parent" android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
```
|
||||
|
||||
#### Multi-color indeterminate animation type
|
||||
@ -211,14 +208,12 @@ In the layout:
|
||||
For linear progress indicator, there are two indeterminate animation types:
|
||||
|
||||
* `disjoint` - animates as repeated cycles with two disjoint segments in the
|
||||
same color at a time. <img src="assets/progressindicator/linear_multicolor_disjoint.gif" alt="Disjointed indeterminate linear progress indicator animation: red indicator
|
||||
travels along track 2x then switches to
|
||||
yellow" width="600"/>
|
||||
same color at a time.
|
||||
<img src=" assets/progressindicator/linear_multicolor_disjoint.gif" alt="Disjointed indeterminate linear progress indicator animation: red indicator travels along track 2x then switches to yellow" width="600"/>
|
||||
|
||||
* `contiguous` - animates as repeated cycles with three adjacent segments in
|
||||
different colors. <img src="assets/progressindicator/linear_multicolor_contiguous.gif" alt="Contiguous indeterminate linear progress indicator
|
||||
animation: red, yellow, blue indicators move sequentially and cover
|
||||
track" width="600"/>
|
||||
different colors.
|
||||
<img src=" assets/progressindicator/linear_multicolor_contiguous.gif" alt="Contiguous indeterminate linear progress indicator animation: red, yellow, blue indicators move sequentially and cover track" width="600"/>
|
||||
|
||||
**Note:** There is a minimum requirement of 3 indicator colors to use the
|
||||
**contiguous** animation. Otherwise, an IllegalArgumentException will be thrown.
|
||||
@ -245,7 +240,8 @@ API and source code:
|
||||
|
||||
The following example shows a determinate circular progress indicator.
|
||||
|
||||
<img src="assets/progressindicator/circular_determinate.gif" alt="Determinate circular progress indicator animation: purple indicator draws a
|
||||
<img src="assets/progressindicator/circular_determinate.gif" alt="Determinate
|
||||
circular progress indicator animation: purple indicator draws a
|
||||
circle clockwise from the
|
||||
top" width="600"/>
|
||||
|
||||
@ -253,13 +249,13 @@ In the layout:
|
||||
|
||||
```xml
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" />
|
||||
```
|
||||
|
||||
The following example shows an indeterminate circular progress indicator.
|
||||
|
||||
<img src="assets/progressindicator/circular_indeterminate.gif" alt="Indeterminate circular progress indicator animation: purple indicator follows
|
||||
<img src="assets/progressindicator/circular_indeterminate.gif" alt="
|
||||
Indeterminate circular progress indicator animation: purple indicator follows
|
||||
a circle clockwise from the
|
||||
top" width="600"/>
|
||||
|
||||
@ -267,9 +263,8 @@ In the layout:
|
||||
|
||||
```xml
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
```
|
||||
|
||||
### Anatomy and key properties
|
||||
@ -278,32 +273,32 @@ A progress indicator consists of a track and an indicator.
|
||||
|
||||

|
||||
|
||||
1. Active indicator
|
||||
2. Track
|
||||
3. Stop indicator
|
||||
1. Active indicator
|
||||
2. Track
|
||||
3. Stop indicator
|
||||
|
||||
#### Common attributes
|
||||
|
||||
The following attributes are shared between linear and circular progress
|
||||
indicators:
|
||||
|
||||
Element | Attribute | Related method(s) | Default value
|
||||
----------------------------------------- | ---------------------------------------- | ------------------------------------------------------------ | -------------
|
||||
**Track thickness** | `app:trackThickness` | `setTrackThickness`<br>`getTrackThickness` | `4dp`
|
||||
**Indicator color** | `app:indicatorColor` | `setIndicatorColor`<br>`getIndicatorColor` | `colorPrimary`
|
||||
**Track color** | `app:trackColor` | `setTrackColor`<br>`getTrackColor` | `colorPrimaryContainer` (linear)<br>`@android:color/transparent` (circular)
|
||||
**Track corner radius** | `app:trackCornerRadius` | `setTrackCornerRadius`<br>`getTrackCornerRadius` | `2dp`
|
||||
**Indicator track gap size** | `app:indicatorTrackGapSize` | `setIndicatorTrackGapSize`<br>`getIndicatorTrackGapSize` | `4dp`
|
||||
**Show animation behavior** | `app:showAnimationBehavior` | `setShowAnimationBehavior`<br>`getShowAnimationBehavior` | `none`
|
||||
**Hide animation behavior** | `app:hideAnimationBehavior` | `setHideAnimationBehavior`<br>`getHideAnimationBehavior` | `none`
|
||||
**Delay (in ms) to show** | `app:showDelay` | N/A | 0
|
||||
**Min delay (in ms) to hide** | `app:minHideDelay` | N/A | 0
|
||||
**Wavelength** | `app:wavelength` | `setWavelength` | 0
|
||||
**Wavelength in determinate mode** | `app:wavelengthDeterminate` | `setWavelengthDeterminate`<br>`getWavelenthDeterminate` | `wavelength`
|
||||
**Wavelength in indeterminate mode** | `app:wavelengthIndeterminate` | `setWavelengthIndeterminate`<br>`getWavelengthIndeterminate` | `wavelength`
|
||||
**Wave amplitude** | `app:waveAmplitude` | `setWaveAmplitude`<br>`getWaveAmplitude` | 0
|
||||
**Wave speed** | `app:waveSpeed` | `setWaveSpeed`<br>`getWaveSpeed` | 0
|
||||
**Indeterminate animator duration scale** | `app:indeterminateAnimatorDurationScale` | `setIndeterminateAnimatorDurationScale` | 1
|
||||
Element | Attribute | Related method(s) | Default value
|
||||
----------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------- | -------------
|
||||
**Track thickness** | `app:trackThickness` | `setTrackThickness`<br>`getTrackThickness` | `4dp`
|
||||
**Indicator color** | `app:indicatorColor` | `setIndicatorColor`<br>`getIndicatorColor` | `colorPrimary`
|
||||
**Track color** | `app:trackColor` | `setTrackColor`<br>`getTrackColor` | `colorPrimaryContainer` (linear)<br>`@android:color/transparent` (circular)
|
||||
**Track corner radius** | `app:trackCornerRadius` | `setTrackCornerRadius`<br>`setTrackCornerRadiusFraction`<br>`getTrackCornerRadius` | `50%`
|
||||
**Indicator track gap size** | `app:indicatorTrackGapSize` | `setIndicatorTrackGapSize`<br>`getIndicatorTrackGapSize` | `4dp`
|
||||
**Show animation behavior** | `app:showAnimationBehavior` | `setShowAnimationBehavior`<br>`getShowAnimationBehavior` | `none`
|
||||
**Hide animation behavior** | `app:hideAnimationBehavior` | `setHideAnimationBehavior`<br>`getHideAnimationBehavior` | `none`
|
||||
**Delay (in ms) to show** | `app:showDelay` | N/A | 0
|
||||
**Min delay (in ms) to hide** | `app:minHideDelay` | N/A | 0
|
||||
**Wavelength** | `app:wavelength` | `setWavelength` | 0
|
||||
**Wavelength in determinate mode** | `app:wavelengthDeterminate` | `setWavelengthDeterminate`<br>`getWavelenthDeterminate` | `wavelength`
|
||||
**Wavelength in indeterminate mode** | `app:wavelengthIndeterminate` | `setWavelengthIndeterminate`<br>`getWavelengthIndeterminate` | `wavelength`
|
||||
**Wave amplitude** | `app:waveAmplitude` | `setWaveAmplitude`<br>`getWaveAmplitude` | 0
|
||||
**Wave speed** | `app:waveSpeed` | `setWaveSpeed`<br>`getWaveSpeed` | 0
|
||||
**Indeterminate animator duration scale** | `app:indeterminateAnimatorDurationScale` | `setIndeterminateAnimatorDurationScale` | 1
|
||||
|
||||
#### Linear type specific attributes
|
||||
|
||||
@ -314,7 +309,7 @@ Element | Attribute | Related me
|
||||
**Indeterminate animation type** | `app:indeterminateAnimationType` | `setIndeterminateAnimationType`<br>`getIndeterminateAnimationType` | `disjoint`
|
||||
**Indicator direction** | `app:indicatorDirectionLinear` | `setIndicatorDirection`<br>`getIndicatorDirection` | `leftToRight`
|
||||
**Track stop indicator size** | `app:trackStopIndicatorSize` | `setTrackStopIndicatorSize`<br>`getTrackStopIndicatorSize` | `4dp`
|
||||
**Track inner corner radius** | `app:trackInnerCornerRadius` | `setTrackInnerCornerRadius`<br>`setTrackInnerCornerRadiusFraction`<br>`getTrackInnerCornerRadius` | `none`
|
||||
**Track inner corner radius** | `app:trackInnerCornerRadius` | `setTrackInnerCornerRadius`<br>`setTrackInnerCornerRadiusFraction`<br>`getTrackInnerCornerRadius` | `none` (use `trackCornerRadius`)
|
||||
|
||||
#### Circular type specific attributes
|
||||
|
||||
@ -352,16 +347,16 @@ In order to comply with the latest accessibility requirements, the
|
||||
`LinearProgressIndicator` and `CircularProgressIndicator` have been updated with
|
||||
additional attributes:
|
||||
|
||||
- `app:indicatorTrackGapSize`: size of the gap between the indicator and the
|
||||
track, 4dp by default.
|
||||
- `app:trackStopIndicatorSize`: size of the stop at the end of the track, 4dp by
|
||||
default. Only applies to the linear determinate configuration.
|
||||
- `app:indicatorTrackGapSize`: size of the gap between the indicator and the
|
||||
track, 4dp by default.
|
||||
- `app:trackStopIndicatorSize`: size of the stop at the end of the track, 4dp
|
||||
by default. Only applies to the linear determinate configuration.
|
||||
|
||||
`*.Legacy` styles have been added to revert to the previous behavior (**not
|
||||
recommended**):
|
||||
|
||||
- `Widget.Material3.LinearProgressIndicator.Legacy`
|
||||
- `Widget.Material3.CircularProgressIndicator.Legacy`
|
||||
- `Widget.Material3.LinearProgressIndicator.Legacy`
|
||||
- `Widget.Material3.CircularProgressIndicator.Legacy`
|
||||
|
||||
## Theming
|
||||
|
||||
@ -391,8 +386,8 @@ circular progress indicators and affects other components:
|
||||
|
||||
```xml
|
||||
<style name="Theme.App" parent="Theme.Material3.*">
|
||||
...
|
||||
<item name="colorPrimary">@color/shrine_pink_100</item>
|
||||
...
|
||||
<item name="colorPrimary">@color/shrine_pink_100</item>
|
||||
</style>
|
||||
```
|
||||
|
||||
@ -401,17 +396,22 @@ all circular progress indicators but does not affect other components:
|
||||
|
||||
```xml
|
||||
<style name="Theme.App" parent="Theme.Material3.*">
|
||||
...
|
||||
<item name="circularProgressIndicatorStyle">@style/Widget.App.CircularProgressIndicator</item>
|
||||
...
|
||||
<item name="circularProgressIndicatorStyle">
|
||||
@style/Widget.App.CircularProgressIndicator
|
||||
</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.App.CircularProgressIndicator" parent="Widget.Material3.CircularProgressIndicator.Legacy">
|
||||
<item name="materialThemeOverlay">@style/ThemeOverlay.App.CircularProgressIndicator</item>
|
||||
<item name="trackThickness">20dp</item>
|
||||
<style name="Widget.App.CircularProgressIndicator"
|
||||
parent="Widget.Material3.CircularProgressIndicator.Legacy">
|
||||
<item name="materialThemeOverlay">
|
||||
@style/ThemeOverlay.App.CircularProgressIndicator
|
||||
</item>
|
||||
<item name="trackThickness">20dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.App.CircularProgressIndicator" parent="">
|
||||
<item name="colorPrimary">@color/shrine_pink_100</item>
|
||||
<item name="colorPrimary">@color/shrine_pink_100</item>
|
||||
</style>
|
||||
```
|
||||
|
||||
@ -419,7 +419,5 @@ Use the style in the layout, which affects only this specific circular progress
|
||||
indicator:
|
||||
|
||||
```xml
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
...
|
||||
style="@style/Widget.App.CircularProgressIndicator" />
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator...style="@style/Widget.App.CircularProgressIndicator" />
|
||||
```
|
||||
|
||||
@ -647,7 +647,36 @@ public abstract class BaseProgressIndicator<S extends BaseProgressIndicatorSpec>
|
||||
*/
|
||||
public void setTrackCornerRadius(@Px int trackCornerRadius) {
|
||||
if (spec.trackCornerRadius != trackCornerRadius) {
|
||||
spec.trackCornerRadius = Math.round(min(trackCornerRadius, spec.trackThickness / 2f));
|
||||
spec.trackCornerRadius = min(trackCornerRadius, spec.trackThickness / 2);
|
||||
spec.useRelativeTrackCornerRadius = false;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative radius of the rounded corner for the indicator and track in pixels.
|
||||
*
|
||||
* @see #setTrackCornerRadiusFraction(float)
|
||||
* @attr ref
|
||||
* com.google.android.material.progressindicator.R.styleable#BaseProgressIndicator_trackCornerRadius
|
||||
*/
|
||||
public float getTrackCornerRadiusFraction() {
|
||||
return spec.trackCornerRadiusFraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the radius of the rounded corner for the indicator and track in fraction of track
|
||||
* thickness.
|
||||
*
|
||||
* @param fraction The fraction of corner radius to track thickness.
|
||||
* @see #getTrackCornerRadiusFraction()
|
||||
* @attr ref
|
||||
* com.google.android.material.progressindicator.R.styleable#BaseProgressIndicator_trackCornerRadius
|
||||
*/
|
||||
public void setTrackCornerRadiusFraction(@FloatRange(from = 0f, to = 0.5f) float fraction) {
|
||||
if (spec.trackCornerRadiusFraction != fraction) {
|
||||
spec.trackCornerRadiusFraction = min(fraction, 0.5f);
|
||||
spec.useRelativeTrackCornerRadius = true;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +54,18 @@ public abstract class BaseProgressIndicatorSpec {
|
||||
*/
|
||||
@Px public int trackCornerRadius;
|
||||
|
||||
/**
|
||||
* The fraction of the track thickness to be used as the corner radius. And the stroke ROUND cap
|
||||
* is used to prevent artifacts like (b/319309456), when 0.5f is specified.
|
||||
*/
|
||||
public float trackCornerRadiusFraction;
|
||||
|
||||
/**
|
||||
* When this is true, the {#link trackCornerRadiusFraction} takes effect. Otherwise, the {@link
|
||||
* trackCornerRadius} takes effect.
|
||||
*/
|
||||
public boolean useRelativeTrackCornerRadius;
|
||||
|
||||
/**
|
||||
* The color array used in the indicator. In determinate mode, only the first item will be used.
|
||||
*/
|
||||
@ -112,11 +124,21 @@ public abstract class BaseProgressIndicatorSpec {
|
||||
trackThickness =
|
||||
getDimensionPixelSize(
|
||||
context, a, R.styleable.BaseProgressIndicator_trackThickness, defaultIndicatorSize);
|
||||
trackCornerRadius =
|
||||
min(
|
||||
getDimensionPixelSize(
|
||||
context, a, R.styleable.BaseProgressIndicator_trackCornerRadius, 0),
|
||||
Math.round(trackThickness / 2f));
|
||||
TypedValue trackCornerRadiusValue =
|
||||
a.peekValue(R.styleable.BaseProgressIndicator_trackCornerRadius);
|
||||
if (trackCornerRadiusValue != null) {
|
||||
if (trackCornerRadiusValue.type == TypedValue.TYPE_DIMENSION) {
|
||||
trackCornerRadius =
|
||||
min(
|
||||
TypedValue.complexToDimensionPixelSize(
|
||||
trackCornerRadiusValue.data, a.getResources().getDisplayMetrics()),
|
||||
trackThickness / 2);
|
||||
useRelativeTrackCornerRadius = false;
|
||||
} else if (trackCornerRadiusValue.type == TypedValue.TYPE_FRACTION) {
|
||||
trackCornerRadiusFraction = min(trackCornerRadiusValue.getFraction(1.0f, 1.0f), 0.5f);
|
||||
useRelativeTrackCornerRadius = true;
|
||||
}
|
||||
}
|
||||
showAnimationBehavior =
|
||||
a.getInt(
|
||||
R.styleable.BaseProgressIndicator_showAnimationBehavior,
|
||||
@ -222,6 +244,27 @@ public abstract class BaseProgressIndicatorSpec {
|
||||
&& ((!isDeterminate && wavelengthIndeterminate > 0)
|
||||
|| (isDeterminate && wavelengthDeterminate > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the track corner radius in pixels.
|
||||
*
|
||||
* <p>If {@link #useRelativeTrackCornerRadius} is true, the track corner radius is calculated
|
||||
* using the track thickness and the track corner radius fraction. Otherwise, the track corner
|
||||
* radius is returned directly.
|
||||
*/
|
||||
public int getTrackCornerRadiusInPx() {
|
||||
return useRelativeTrackCornerRadius
|
||||
? (int) (trackThickness * trackCornerRadiusFraction)
|
||||
: trackCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stroke ROUND cap should be used to prevent artifacts like (b/319309456),
|
||||
* when fully rounded corners are specified.
|
||||
*/
|
||||
public boolean useStrokeCap() {
|
||||
return useRelativeTrackCornerRadius && trackCornerRadiusFraction == 0.5f;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
void validateSpec() {
|
||||
|
||||
@ -58,8 +58,6 @@ final class CircularDrawingDelegate extends DrawingDelegate<CircularProgressIndi
|
||||
private float cachedAmplitude;
|
||||
private int cachedWavelength;
|
||||
private float cachedRadius;
|
||||
// For full round ends, the stroke ROUND cap is used to prevent artifacts like (b/319309456).
|
||||
private boolean useStrokeCap;
|
||||
private boolean drawingDeterminateIndicator;
|
||||
|
||||
// This will be used in the ESCAPE hide animation. The start and end fraction in track will be
|
||||
@ -138,10 +136,9 @@ final class CircularDrawingDelegate extends DrawingDelegate<CircularProgressIndi
|
||||
-outerRadiusWithInset, -outerRadiusWithInset, outerRadiusWithInset, outerRadiusWithInset);
|
||||
|
||||
// These are used when drawing the indicator and track.
|
||||
useStrokeCap = spec.trackThickness / 2f <= spec.trackCornerRadius;
|
||||
displayedTrackThickness = spec.trackThickness * trackThicknessFraction;
|
||||
displayedCornerRadius =
|
||||
min(spec.trackThickness / 2f, spec.trackCornerRadius) * trackThicknessFraction;
|
||||
min(spec.trackThickness / 2, spec.getTrackCornerRadiusInPx()) * trackThicknessFraction;
|
||||
displayedAmplitude = spec.waveAmplitude * trackThicknessFraction;
|
||||
|
||||
// Further adjusts the radius for animated visibility change.
|
||||
@ -348,7 +345,7 @@ final class CircularDrawingDelegate extends DrawingDelegate<CircularProgressIndi
|
||||
} else {
|
||||
// Draws the arc with ROUND cap if the corner radius is half of the track thickness.
|
||||
paint.setStyle(Style.STROKE);
|
||||
paint.setStrokeCap(useStrokeCap ? Cap.ROUND : Cap.BUTT);
|
||||
paint.setStrokeCap(spec.useStrokeCap() ? Cap.ROUND : Cap.BUTT);
|
||||
// Draws the arc without rounded corners.
|
||||
float startDegreeWithoutCorners = startDegree + displayedCornerRadiusInDegree;
|
||||
float arcDegreeWithoutCorners = arcDegree - displayedCornerRadiusInDegree * 2;
|
||||
@ -374,7 +371,7 @@ final class CircularDrawingDelegate extends DrawingDelegate<CircularProgressIndi
|
||||
}
|
||||
|
||||
// Draws rounded rectangles if ROUND cap is not used and the corner radius is bigger than 0.
|
||||
if (!useStrokeCap && displayedCornerRadius > 0) {
|
||||
if (!spec.useStrokeCap() && displayedCornerRadius > 0) {
|
||||
paint.setStyle(Style.FILL);
|
||||
drawRoundedBlock(canvas, paint, endPoints.first, blockWidth, displayedTrackThickness);
|
||||
drawRoundedBlock(canvas, paint, endPoints.second, blockWidth, displayedTrackThickness);
|
||||
|
||||
@ -55,7 +55,6 @@ final class LinearDrawingDelegate extends DrawingDelegate<LinearProgressIndicato
|
||||
private float displayedAmplitude;
|
||||
private float adjustedWavelength;
|
||||
private int cachedWavelength;
|
||||
private boolean useStrokeCap;
|
||||
private boolean drawingDeterminateIndicator;
|
||||
|
||||
// This will be used in the ESCAPE hide animation. The start and end fraction in track will be
|
||||
@ -124,14 +123,11 @@ final class LinearDrawingDelegate extends DrawingDelegate<LinearProgressIndicato
|
||||
// These are set for the drawing the indicator and track.
|
||||
displayedTrackThickness = spec.trackThickness * trackThicknessFraction;
|
||||
displayedCornerRadius =
|
||||
min(spec.trackThickness / 2f, spec.trackCornerRadius) * trackThicknessFraction;
|
||||
min(spec.trackThickness / 2, spec.getTrackCornerRadiusInPx()) * trackThicknessFraction;
|
||||
displayedAmplitude = spec.waveAmplitude * trackThicknessFraction;
|
||||
displayedInnerCornerRadius =
|
||||
min(spec.trackThickness / 2f, spec.getTrackInnerCornerRadiusInPx())
|
||||
* trackThicknessFraction;
|
||||
useStrokeCap =
|
||||
spec.trackThickness / 2f <= spec.trackCornerRadius
|
||||
&& displayedCornerRadius == displayedInnerCornerRadius;
|
||||
|
||||
// Further adjusts the canvas for animated visibility change.
|
||||
if (isShowing || isHiding) {
|
||||
@ -319,7 +315,7 @@ final class LinearDrawingDelegate extends DrawingDelegate<LinearProgressIndicato
|
||||
// Draws the path with ROUND cap if the corner radius is half of the track
|
||||
// thickness.
|
||||
paint.setStyle(Style.STROKE);
|
||||
paint.setStrokeCap(useStrokeCap ? Cap.ROUND : Cap.BUTT);
|
||||
paint.setStrokeCap(spec.useStrokeCap() ? Cap.ROUND : Cap.BUTT);
|
||||
|
||||
// If start rounded block is on the left of end rounded block, draws the path with the
|
||||
// start and end rounded blocks.
|
||||
@ -343,7 +339,7 @@ final class LinearDrawingDelegate extends DrawingDelegate<LinearProgressIndicato
|
||||
phaseFraction);
|
||||
canvas.drawPath(displayedActivePath, paint);
|
||||
}
|
||||
if (!useStrokeCap) {
|
||||
if (!spec.useStrokeCap()) {
|
||||
if (startBlockCenterX > 0 && startCornerRadius > 0) {
|
||||
// Draws the start rounded block.
|
||||
drawRoundedBlock(
|
||||
|
||||
@ -130,12 +130,17 @@ public final class LinearProgressIndicatorSpec extends BaseProgressIndicatorSpec
|
||||
|
||||
public int getTrackInnerCornerRadiusInPx() {
|
||||
return !hasInnerCornerRadius
|
||||
? trackCornerRadius
|
||||
? getTrackCornerRadiusInPx()
|
||||
: useRelativeTrackInnerCornerRadius
|
||||
? (int) (trackThickness * trackInnerCornerRadiusFraction)
|
||||
: trackInnerCornerRadius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useStrokeCap() {
|
||||
return super.useStrokeCap() && getTrackInnerCornerRadiusInPx() == getTrackCornerRadiusInPx();
|
||||
}
|
||||
|
||||
@Override
|
||||
void validateSpec() {
|
||||
super.validateSpec();
|
||||
@ -145,7 +150,8 @@ public final class LinearProgressIndicatorSpec extends BaseProgressIndicatorSpec
|
||||
}
|
||||
if (indeterminateAnimationType
|
||||
== LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS) {
|
||||
if ((trackCornerRadius > 0 || (hasInnerCornerRadius && getTrackInnerCornerRadiusInPx() > 0))
|
||||
if ((getTrackCornerRadiusInPx() > 0
|
||||
|| (hasInnerCornerRadius && getTrackInnerCornerRadiusInPx() > 0))
|
||||
&& indicatorTrackGapSize == 0) {
|
||||
// Throws an exception if trying to use the cornered indicator/track with contiguous
|
||||
// indeterminate animation type without gap.
|
||||
|
||||
@ -24,9 +24,9 @@
|
||||
<!--
|
||||
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.
|
||||
initialization. Use 50% for fully rounded corners.
|
||||
-->
|
||||
<attr name="trackCornerRadius" format="dimension" />
|
||||
<attr name="trackCornerRadius" format="dimension|fraction" />
|
||||
<!--
|
||||
The indicator color (or colors in an array). By default, it uses theme
|
||||
primary color.
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
<item name="trackThickness">@dimen/m3_comp_progress_indicator_linear_track_thickness</item>
|
||||
<item name="trackColor">@macro/m3_comp_progress_indicator_track_color</item>
|
||||
<item name="indicatorColor">@macro/m3_comp_progress_indicator_active_indicator_color</item>
|
||||
<item name="trackCornerRadius">2dp</item>
|
||||
<item name="trackCornerRadius">50%</item>
|
||||
<item name="indicatorTrackGapSize">@dimen/m3_comp_progress_indicator_linear_track_active_indicator_space</item>
|
||||
<item name="trackStopIndicatorSize">@dimen/m3_comp_progress_indicator_linear_stop_indicator_size</item>
|
||||
</style>
|
||||
@ -95,7 +95,7 @@
|
||||
<item name="indicatorSize">@dimen/m3_comp_progress_indicator_circular_size</item>
|
||||
<item name="indicatorColor">@macro/m3_comp_progress_indicator_active_indicator_color</item>
|
||||
<item name="trackColor">@macro/m3_comp_progress_indicator_track_color</item>
|
||||
<item name="trackCornerRadius">2dp</item>
|
||||
<item name="trackCornerRadius">50%</item>
|
||||
<item name="indicatorTrackGapSize">@dimen/m3_comp_progress_indicator_circular_track_active_indicator_space</item>
|
||||
<item name="indeterminateTrackVisible">false</item>
|
||||
</style>
|
||||
@ -104,14 +104,14 @@
|
||||
<item name="trackThickness">@dimen/mtrl_progress_circular_track_thickness_small</item>
|
||||
<item name="indicatorSize">@dimen/mtrl_progress_circular_size_small</item>
|
||||
<item name="indicatorInset">@dimen/mtrl_progress_circular_inset_small</item>
|
||||
<item name="trackCornerRadius">1.5dp</item>
|
||||
<item name="trackCornerRadius">50%</item>
|
||||
<item name="indicatorTrackGapSize">3dp</item>
|
||||
</style>
|
||||
<style name="Widget.Material3.CircularProgressIndicator.ExtraSmall">
|
||||
<item name="trackThickness">@dimen/mtrl_progress_circular_track_thickness_extra_small</item>
|
||||
<item name="indicatorSize">@dimen/mtrl_progress_circular_size_extra_small</item>
|
||||
<item name="indicatorInset">@dimen/mtrl_progress_circular_inset_extra_small</item>
|
||||
<item name="trackCornerRadius">1.25dp</item>
|
||||
<item name="trackCornerRadius">50%</item>
|
||||
<item name="indicatorTrackGapSize">2dp</item>
|
||||
</style>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user