1818
1919import android .content .Context ;
2020import android .graphics .Typeface ;
21+ import android .graphics .drawable .Animatable ;
22+ import android .graphics .drawable .Drawable ;
23+ import android .os .Build ;
2124import android .support .annotation .CallSuper ;
2225import android .support .annotation .ColorInt ;
26+ import android .support .annotation .DrawableRes ;
2327import android .support .annotation .RestrictTo ;
2428import android .support .graphics .drawable .AnimatedVectorDrawableCompat ;
2529import android .support .v4 .content .ContextCompat ;
@@ -48,6 +52,10 @@ public class StepTab extends RelativeLayout {
4852
4953 private static final float ALPHA_OPAQUE = 1.0f ;
5054
55+ private static final float HALF_SIZE_SCALE = 0.5f ;
56+
57+ private static final float FULL_SIZE_SCALE = 1.0f ;
58+
5159 @ ColorInt
5260 private int mUnselectedColor ;
5361
@@ -108,7 +116,7 @@ public StepTab(Context context, AttributeSet attrs, int defStyleAttr) {
108116 Typeface typeface = mStepTitle .getTypeface ();
109117 mNormalTypeface = Typeface .create (typeface , Typeface .NORMAL );
110118 mBoldTypeface = Typeface .create (typeface , Typeface .BOLD );
111- AnimatedVectorDrawableCompat avd = createCircleToWarningDrawable ();
119+ Drawable avd = createCircleToWarningDrawable ();
112120 mStepIconBackground .setImageDrawable (avd );
113121 }
114122
@@ -123,11 +131,13 @@ public void toggleDividerVisibility(boolean show) {
123131
124132 /**
125133 * Updates the UI state of the tab and sets {@link #mCurrentState} based on the arguments.
126- * @param error <code>true</code> if an error/warning should be shown, if <code>true</code> a warning will be shown
127- * @param done true the step was completed, if warning is not shown and this is <code>true</code> a done indicator will be shown
134+ *
135+ * @param error <code>true</code> if an error/warning should be shown, if <code>true</code> a warning will be shown
136+ * @param done true the step was completed, if warning is not shown and this is <code>true</code> a done indicator will be shown
128137 * @param current true if this is the currently selected step
129138 */
130139 public void updateState (final boolean error , final boolean done , final boolean current ) {
140+ // FIXME: 05/03/2017 stop tabs from changing positions due to changing font type (does not happen e.g. on API 16, investigate further)
131141 mStepTitle .setTypeface (current ? mBoldTypeface : mNormalTypeface );
132142
133143 if (error ) {
@@ -177,13 +187,29 @@ public void setDividerWidth(int dividerWidth) {
177187 : getResources ().getDimensionPixelOffset (R .dimen .ms_step_tab_divider_length );
178188 }
179189
180- // FIXME: 05/03/2017 stop tabs from changing positions due to changing font type (does not happen e.g. on API 16, investigate further)
181- private AnimatedVectorDrawableCompat createCircleToWarningDrawable () {
182- return AnimatedVectorDrawableCompat .create (getContext (), R .drawable .ms_avd_circle_to_warning );
190+ private Drawable createCircleToWarningDrawable () {
191+ return createAnimatedVectorDrawable (R .drawable .ms_avd_circle_to_warning );
192+ }
193+
194+ private Drawable createWarningToCircleDrawable () {
195+ return createAnimatedVectorDrawable (R .drawable .ms_avd_warning_to_circle );
183196 }
184197
185- private AnimatedVectorDrawableCompat createWarningToCircleDrawable () {
186- return AnimatedVectorDrawableCompat .create (getContext (), R .drawable .ms_avd_warning_to_circle );
198+ /**
199+ * Inflates an animated vector drawable. On Lollipop+ this uses the native {@link android.graphics.drawable.AnimatedVectorDrawable}
200+ * and below it inflates the drawable as a {@link AnimatedVectorDrawableCompat}.
201+ *
202+ * @param animatedVectorDrawableResId resource ID for the animated vector
203+ * @return animated vector drawable
204+ */
205+ public Drawable createAnimatedVectorDrawable (@ DrawableRes int animatedVectorDrawableResId ) {
206+ Context context = getContext ();
207+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
208+ Drawable drawable = context .getDrawable (animatedVectorDrawableResId );
209+ return drawable .getConstantState ().newDrawable (context .getResources ());
210+ } else {
211+ return AnimatedVectorDrawableCompat .create (context , animatedVectorDrawableResId );
212+ }
187213 }
188214
189215 /**
@@ -192,10 +218,10 @@ private AnimatedVectorDrawableCompat createWarningToCircleDrawable() {
192218 * when transitioning to other states, e.g. which views to hide or tint.</p>
193219 * <p>Subclasses include:</p>
194220 * <ul>
195- * <li>{@link InactiveNumberState} - for when we show the step number, but this step still hasn't been reached</li>
196- * <li>{@link ActiveNumberState} - for when we show the step number of the currently active tab</li>
197- * <li>{@link DoneState} - for when the step has already been completed and the user has moved to the next step</li>
198- * <li>{@link WarningState} - for when there has been an error on this step (if {@link StepperLayout#setShowErrorStateEnabled(boolean)} or <code>ms_showErrorStateEnabled</code> was set to <i>true</i>)</li>
221+ * <li>{@link InactiveNumberState} - for when we show the step number, but this step still hasn't been reached</li>
222+ * <li>{@link ActiveNumberState} - for when we show the step number of the currently active tab</li>
223+ * <li>{@link DoneState} - for when the step has already been completed and the user has moved to the next step</li>
224+ * <li>{@link WarningState} - for when there has been an error on this step (if {@link StepperLayout#setShowErrorStateEnabled(boolean)} or <code>ms_showErrorStateEnabled</code> was set to <i>true</i>)</li>
199225 * </ul>
200226 */
201227 private abstract class AbstractState {
@@ -230,9 +256,9 @@ private abstract class AbstractNumberState extends AbstractState {
230256 @ Override
231257 @ CallSuper
232258 protected void changeToWarning () {
233- AnimatedVectorDrawableCompat avd = createCircleToWarningDrawable ();
259+ Drawable avd = createCircleToWarningDrawable ();
234260 mStepIconBackground .setImageDrawable (avd );
235- avd .start ();
261+ (( Animatable ) avd ) .start ();
236262 super .changeToWarning ();
237263 }
238264
@@ -301,24 +327,17 @@ protected void changeToActiveNumber() {
301327
302328 @ Override
303329 protected void changeToWarning () {
304- AnimatedVectorDrawableCompat avd = createCircleToWarningDrawable ();
330+ Drawable avd = createCircleToWarningDrawable ();
305331 mStepIconBackground .setImageDrawable (avd );
306- avd .start ();
332+ (( Animatable ) avd ) .start ();
307333 super .changeToWarning ();
308334 }
309335 }
310336
311337 private class WarningState extends AbstractState {
312338
313- private static final float HALF_SIZE_SCALE = 0.5f ;
314- private static final float FULL_SIZE_SCALE = 1.0f ;
315-
316339 @ Override
317340 protected void changeToDone () {
318- AnimatedVectorDrawableCompat avd = createWarningToCircleDrawable ();
319- mStepIconBackground .setImageDrawable (avd );
320- avd .start ();
321-
322341 animateViewIn (mStepDoneIndicator );
323342
324343 mStepIconBackground .setColorFilter (mSelectedColor );
@@ -328,10 +347,6 @@ protected void changeToDone() {
328347
329348 @ Override
330349 protected void changeToInactiveNumber () {
331- AnimatedVectorDrawableCompat avd = createWarningToCircleDrawable ();
332- mStepIconBackground .setImageDrawable (avd );
333- avd .start ();
334-
335350 animateViewIn (mStepNumber );
336351
337352 mStepIconBackground .setColorFilter (mUnselectedColor );
@@ -343,10 +358,6 @@ protected void changeToInactiveNumber() {
343358
344359 @ Override
345360 protected void changeToActiveNumber () {
346- AnimatedVectorDrawableCompat avd = createWarningToCircleDrawable ();
347- mStepIconBackground .setImageDrawable (avd );
348- avd .start ();
349-
350361 animateViewIn (mStepNumber );
351362
352363 mStepIconBackground .setColorFilter (mSelectedColor );
@@ -355,6 +366,10 @@ protected void changeToActiveNumber() {
355366 }
356367
357368 private void animateViewIn (final View view ) {
369+ Drawable avd = createWarningToCircleDrawable ();
370+ mStepIconBackground .setImageDrawable (avd );
371+ ((Animatable ) avd ).start ();
372+
358373 view .setVisibility (View .VISIBLE );
359374 view .setAlpha (ALPHA_TRANSPARENT );
360375 view .setScaleX (HALF_SIZE_SCALE );
0 commit comments