2323
2424import android .animation .AnimatorSet ;
2525import android .content .Context ;
26- import android .content .res .Resources ;
2726import android .content .res .TypedArray ;
2827import android .graphics .Canvas ;
2928import android .graphics .drawable .Drawable ;
4039import androidx .annotation .Px ;
4140import androidx .annotation .VisibleForTesting ;
4241import androidx .vectordrawable .graphics .drawable .Animatable2Compat .AnimationCallback ;
43- import com .google .android .material .color .MaterialColors ;
4442import java .lang .annotation .Retention ;
4543import java .lang .annotation .RetentionPolicy ;
4644
5250 */
5351public class ProgressIndicator extends ProgressBar {
5452
55- private static final int DEF_STYLE_RES =
53+ protected static final int DEF_STYLE_RES =
5654 R .style .Widget_MaterialComponents_ProgressIndicator_Linear_Determinate ;
55+ protected static final float DEFAULT_OPACITY = 0.2f ;
56+ protected static final int MAX_ALPHA = 255 ;
5757
5858 // Constants for track shape.
5959
@@ -88,9 +88,6 @@ public class ProgressIndicator extends ProgressBar {
8888 /** The progress indicator will expand from and shrink to the central line of the indicator. */
8989 public static final int GROW_MODE_BIDIRECTIONAL = 3 ;
9090
91- private static final float DEFAULT_OPACITY = 0.2f ;
92- private static final int MAX_ALPHA = 255 ;
93-
9491 /**
9592 * The maximum time, in milliseconds, that the requested hide action is allowed to wait once
9693 * {@link #show()} is called.
@@ -162,8 +159,8 @@ public ProgressIndicator(
162159 context = getContext ();
163160
164161 spec = new ProgressIndicatorSpec ();
165- loadDefaultAttributes ( context . getResources (), spec );
166- loadAttributes (context , attrs , defStyleAttr , defStyleRes );
162+ spec . loadFromAttributes ( context , attrs , defStyleAttr , defStyleRes );
163+ loadExtraAttributes (context , attrs , defStyleAttr , defStyleRes );
167164
168165 if (spec .indicatorType != CUSTOM ) {
169166 initializeDrawables ();
@@ -172,88 +169,13 @@ public ProgressIndicator(
172169
173170 // ******************** Initialization **********************
174171
175- /** Loads some default dimensions from resource file. */
176- private static void loadDefaultAttributes (Resources resources , ProgressIndicatorSpec spec ) {
177- spec .indicatorWidth = resources .getDimensionPixelSize (R .dimen .mtrl_progress_indicator_width );
178- spec .circularInset = resources .getDimensionPixelSize (R .dimen .mtrl_progress_circular_inset );
179- spec .circularRadius = resources .getDimensionPixelSize (R .dimen .mtrl_progress_circular_radius );
180- // By default, rounded corners are not applied.
181- spec .indicatorCornerRadius = 0 ;
182- }
183-
184- /** Loads attributes defined in layout or style files. */
185- private void loadAttributes (
186- Context context , AttributeSet attrs , int defStyleAttr , int defStyleRes ) {
172+ /** Loads extra attributes specifically defined for material progress indicator. */
173+ private void loadExtraAttributes (
174+ @ NonNull Context context , AttributeSet attrs , int defStyleAttr , int defStyleRes ) {
187175 TypedArray a =
188176 context .obtainStyledAttributes (
189177 attrs , R .styleable .ProgressIndicator , defStyleAttr , defStyleRes );
190178
191- spec .indicatorType = a .getInt (R .styleable .ProgressIndicator_indicatorType , LINEAR );
192- spec .indicatorWidth =
193- a .getDimensionPixelSize (R .styleable .ProgressIndicator_indicatorWidth , spec .indicatorWidth );
194- spec .circularInset =
195- a .getDimensionPixelSize (R .styleable .ProgressIndicator_circularInset , spec .circularInset );
196- spec .circularRadius =
197- a .getDimensionPixelSize (R .styleable .ProgressIndicator_circularRadius , spec .circularRadius );
198- if (spec .indicatorType == CIRCULAR && spec .circularRadius < spec .indicatorWidth / 2 ) {
199- // Throws an exception if circularRadius is less than half of the indicatorWidth, which will
200- // result in a part of the inner side of the indicator overshoots the center, and the visual
201- // becomes undefined.
202- throw new IllegalArgumentException (
203- "The circularRadius cannot be less than half of the indicatorWidth." );
204- }
205- spec .inverse = a .getBoolean (R .styleable .ProgressIndicator_inverse , false );
206- spec .growMode = a .getInt (R .styleable .ProgressIndicator_growMode , GROW_MODE_NONE );
207-
208- // Gets indicator colors from resource if existed, otherwise use indicatorColor attribute.
209- if (a .hasValue (R .styleable .ProgressIndicator_indicatorColors )) {
210- spec .indicatorColors =
211- getResources ()
212- .getIntArray (a .getResourceId (R .styleable .ProgressIndicator_indicatorColors , -1 ));
213- if (a .hasValue (R .styleable .ProgressIndicator_indicatorColor )) {
214- // Throws an exception if both indicatorColors and indicatorColor exist in attribute set.
215- throw new IllegalArgumentException (
216- "Attributes indicatorColors and indicatorColor cannot be used at the same time." );
217- } else if (spec .indicatorColors .length == 0 ) {
218- // Throws an exception if indicatorColor doesn't exist and indicatorColors is empty.
219- throw new IllegalArgumentException (
220- "indicatorColors cannot be empty when indicatorColor is not used." );
221- }
222- } else if (a .hasValue (R .styleable .ProgressIndicator_indicatorColor )) {
223- spec .indicatorColors =
224- new int [] {a .getColor (R .styleable .ProgressIndicator_indicatorColor , -1 )};
225- } else {
226- // Uses theme primary color for indicator if neither indicatorColor nor indicatorColors exists
227- // in attribute set.
228- spec .indicatorColors = new int [] {MaterialColors .getColor (context , R .attr .colorPrimary , -1 )};
229- }
230- // Gets track color if defined, otherwise, use indicator color with the disable alpha value.
231- if (a .hasValue (R .styleable .ProgressIndicator_trackColor )) {
232- spec .trackColor = a .getColor (R .styleable .ProgressIndicator_trackColor , -1 );
233- } else {
234- spec .trackColor = spec .indicatorColors [0 ];
235-
236- TypedArray disabledAlphaArray =
237- context .getTheme ().obtainStyledAttributes (new int [] {android .R .attr .disabledAlpha });
238- float defaultOpacity = disabledAlphaArray .getFloat (0 , DEFAULT_OPACITY );
239- disabledAlphaArray .recycle ();
240-
241- int trackAlpha = (int ) (MAX_ALPHA * defaultOpacity );
242- spec .trackColor = MaterialColors .compositeARGBWithAlpha (spec .trackColor , trackAlpha );
243- }
244- // Gets linearSeamless or overrides it if necessary.
245- if (isEligibleToSeamless ()) {
246- spec .linearSeamless = a .getBoolean (R .styleable .ProgressIndicator_linearSeamless , true );
247- } else {
248- spec .linearSeamless = false ;
249- }
250- // Gets the radius of rounded corners if defined, otherwise, use 0 (sharp corner).
251- setIndicatorCornerRadius (
252- a .getDimensionPixelSize (
253- R .styleable .ProgressIndicator_indicatorCornerRadius , spec .indicatorCornerRadius ));
254- // Sets if is indeterminate.
255- setIndeterminate (a .getBoolean (R .styleable .ProgressIndicator_android_indeterminate , false ));
256-
257179 if (a .hasValue (R .styleable .ProgressIndicator_minHideDelay )) {
258180 int minHideDelayUncapped = a .getInt (R .styleable .ProgressIndicator_minHideDelay , -1 );
259181 minHideDelay = min (minHideDelayUncapped , MAX_HIDE_DELAY );
0 commit comments