Skip to content

Commit a5d578c

Browse files
authored
Stepper feedback enhancements (#168)
* added missing tests for stepper feedback composite and factory * added missing tests for tabs and disabled bottom navigation feedback types refactored tests to reuse common setup methods * added an option to stop child steps from receiving touch events as one of stepper feedback types * Split 'content' stepper feedback type into 'content_progress' & 'content_fade' Added 'content_overlay' stepper feedback type * Added an option to change fade out alpha for 'content_fade' stepper feedback type * Added an option to change overlay background drawable for 'content_overlay' stepper feedback type
1 parent be28527 commit a5d578c

37 files changed

+1303
-105
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88
### Added
99
- `setEndButtonVisible` and `setBackButtonVisible` methods in `StepViewModel.Builder` for toggling button visibility (issue #104)
1010
- New stepper type `none` which shows no progress indicator for the steps (issue #154)
11+
- New stepper feedback type `disabled_content_interaction` which intercepts touch events on the steps' content and ignores them during operation.
12+
- New stepper feedback type `content_overlay` which shows a dimmed overlay over the content.
13+
- An option to specify the background drawable for `content_overlay` stepper feedback type via `ms_stepperFeedback_contentOverlayBackground`.
14+
- An option to specify the fade out alpha for `content_fade` stepper feedback type via `ms_stepperFeedback_contentFadeAlpha` attribute.
1115

1216
### Changed
13-
- Updated Android Support Library version to `25.4.0` to support vector animations without a pre-Lollipop fallback (issue #154)
14-
- Changed `setNextButtonLabel` methods in `StepViewModel.Builder` to `setEndButtonLabel` so that it works for both Next and Complete buttons (issue #107)
17+
- **Breaking change:** Updated Android Support Library version to `25.4.0` to support vector animations without a pre-Lollipop fallback (issue #154)
18+
- **Breaking change:** Changed `setNextButtonLabel` methods in `StepViewModel.Builder` to `setEndButtonLabel` so that it works for both Next and Complete buttons (issue #107)
19+
- **Breaking change:** Split `content` stepper feedback type into `content_progress` and `content_fade`.
1520

1621
[Unreleased]: https://github.com/stepstone-tech/android-material-stepper/compare/v3.3.0...develop

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,12 @@ If you want to keep the error displayed when going back to the previous step you
356356
### Stepper feedback
357357
It is possible to show stepper feedback for ongoing operations (see [Stepper feedback](https://material.io/guidelines/components/steppers.html#steppers-types-of-steppers)).
358358
To do so you firstly need to set ```ms_stepperFeedbackType``` to one or more of:
359-
* ```tabs``` - shows a progress message instead of the tabs during operation,
360-
* ```content``` - shows a progress bar on top of the steps' content and partially fades the content out during operation,
359+
* ```tabs``` - shows a progress message instead of the tabs during operation.
360+
* ```content_progress``` - shows a progress bar on top of the steps' content.
361+
* ```content_fade``` - partially fades the content out during operation (should not be used together with ```content_overlay```). You can change the default fade amount with `ms_stepperFeedback_contentFadeAlpha` attribute.
362+
* ```content_overlay``` - shows a dimmed overlay over the content during the operation (should not be used together with ```content_fade```). You can change the overlay background with `ms_stepperFeedback_contentOverlayBackground` attribute.
361363
* ```disabled_bottom_navigation``` - disables the buttons in the bottom navigation during operation. In order to see that the buttons are disabled on the bottom navigation bar, make sure that the button colors are assigned using color selectors with a disabled state (see the sample app).
364+
* ```disabled_content_interaction``` - intercepts touch events on the steps' content and ignores them during operation.
362365

363366
The default is ```none``` which does nothing. It is possible to use multiple flags together.
364367

@@ -480,7 +483,9 @@ For advanced styling please see [StepperLayout style attributes](#stepperlayout-
480483
| *ms_showErrorStateEnabled* | boolean | Flag indicating whether to show the error state. Only applicable for 'tabs' type. False by default. |
481484
| *ms_showErrorStateOnBackEnabled*| boolean | Flag indicating whether to keep showing the error state when user moves back. Only applicable for 'tabs' type. False by default. |
482485
| *ms_tabNavigationEnabled* | boolean | Flag indicating whether step navigation is possible by clicking on the tabs directly. Only applicable for 'tabs' type. True by default. |
483-
| *ms_stepperFeedbackType* | flag(s): `none` or `tabs`, `content` & `disabled_bottom_navigation` | Type(s) of stepper feedback. Can be a combination of `tabs`, `content` & `disabled_bottom_navigation`. Default is `none`.|
486+
| *ms_stepperFeedbackType* | flag(s): `none` or `tabs`, `content_progress`, `content_fade`, `content_overlay`, `disabled_bottom_navigation` & `disabled_content_interaction` | Type(s) of stepper feedback. Can be a combination of `tabs`, `content_progress`, `content_fade`, `content_overlay`, `disabled_bottom_navigation` & `disabled_content_interaction`. Default is `none`.|
487+
| *ms_stepperFeedback_contentFadeAlpha* | float | An alpha value from 0 to 1.0f to be used for the faded out view if `content_fade` stepper feedback type is set. 0.5f by default. |
488+
| *ms_stepperFeedback_contentOverlayBackground* | reference | Background to be used for the overlay on top of the content if `content_overlay` stepper feedback type is set. |
484489
| *ms_showBottomNavigation* | boolean | Flag indicating if the Bottom Navigation bar should be shown on the layout. True by default. |
485490
| *ms_stepperLayoutTheme* | reference | Theme to use for even more custom styling of the stepper layout. It is recommended that it should extend @style/MSDefaultStepperLayoutTheme, which is the default theme used. |
486491
@@ -496,6 +501,7 @@ A list of `ms_stepperLayoutTheme` attributes responsible for styling of StepperL
496501
| *ms_completeNavigationButtonStyle*| Used by ms_stepCompleteButton in layout/ms_stepper_layout |
497502
| *ms_colorableProgressBarStyle* | Used by ms_stepProgressBar in layout/ms_stepper_layout |
498503
| *ms_stepPagerProgressBarStyle* | Used by ms_stepPagerProgressBar in layout/ms_stepper_layout |
504+
| *ms_stepPagerOverlayStyle* | Used by ms_stepPagerOverlay in layout/ms_stepper_layout |
499505
| *ms_stepTabsScrollViewStyle* | Used by ms_stepTabsScrollView in layout/ms_tabs_container |
500506
| *ms_stepTabsInnerContainerStyle* | Used by ms_stepTabsInnerContainer in layout/ms_tabs_container |
501507
| *ms_stepTabsProgressMessageStyle* | Used by ms_stepTabsProgressMessage in layout/ms_tabs_container|

material-stepper/src/main/java/com/stepstone/stepper/StepperLayout.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import android.support.annotation.AttrRes;
2626
import android.support.annotation.ColorInt;
2727
import android.support.annotation.DrawableRes;
28+
import android.support.annotation.FloatRange;
2829
import android.support.annotation.IntRange;
2930
import android.support.annotation.NonNull;
3031
import android.support.annotation.Nullable;
@@ -237,6 +238,12 @@ public void goToPrevStep() {
237238

238239
private StepperFeedbackType mStepperFeedbackType;
239240

241+
@FloatRange(from = 0.0f, to = 1.0f)
242+
private float mContentFadeAlpha = AnimationUtil.ALPHA_HALF;
243+
244+
@DrawableRes
245+
private int mContentOverlayBackground;
246+
240247
private int mCurrentStepPosition;
241248

242249
private boolean mShowErrorStateEnabled;
@@ -627,6 +634,23 @@ public void setFeedbackType(int feedbackTypeMask) {
627634
mStepperFeedbackType = StepperFeedbackTypeFactory.createType(mFeedbackTypeMask, this);
628635
}
629636

637+
/**
638+
* @return An alpha value from 0 to 1.0f to be used for the faded out view if 'content_fade' stepper feedback is set. 0.5f by default.
639+
*/
640+
@FloatRange(from = 0.0f, to = 1.0f)
641+
public float getContentFadeAlpha() {
642+
return mContentFadeAlpha;
643+
}
644+
645+
/**
646+
* @return Background res ID to be used for the overlay on top of the content
647+
* if 'content_overlay' stepper feedback type is set. 0 if default background should be used.
648+
*/
649+
@DrawableRes
650+
public int getContentOverlayBackground() {
651+
return mContentOverlayBackground;
652+
}
653+
630654
@SuppressWarnings("RestrictedApi")
631655
private void init(AttributeSet attrs, @AttrRes int defStyleAttr) {
632656
initDefaultValues();
@@ -792,6 +816,14 @@ private void extractValuesFromAttributes(AttributeSet attrs, @AttrRes int defSty
792816
mFeedbackTypeMask = a.getInt(R.styleable.StepperLayout_ms_stepperFeedbackType, StepperFeedbackType.NONE);
793817
}
794818

819+
if (a.hasValue(R.styleable.StepperLayout_ms_stepperFeedback_contentFadeAlpha)) {
820+
mContentFadeAlpha = a.getFloat(R.styleable.StepperLayout_ms_stepperFeedback_contentFadeAlpha, AnimationUtil.ALPHA_HALF);
821+
}
822+
823+
if (a.hasValue(R.styleable.StepperLayout_ms_stepperFeedback_contentOverlayBackground)) {
824+
mContentOverlayBackground = a.getResourceId(R.styleable.StepperLayout_ms_stepperFeedback_contentOverlayBackground, 0);
825+
}
826+
795827
mShowErrorStateOnBackEnabled = a.getBoolean(R.styleable.StepperLayout_ms_showErrorStateOnBack, false);
796828
mShowErrorStateOnBackEnabled = a.getBoolean(R.styleable.StepperLayout_ms_showErrorStateOnBackEnabled, mShowErrorStateOnBackEnabled);
797829

material-stepper/src/main/java/com/stepstone/stepper/internal/feedback/ContentStepperFeedbackType.java renamed to material-stepper/src/main/java/com/stepstone/stepper/internal/feedback/ContentFadeStepperFeedbackType.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,43 @@
1616

1717
package com.stepstone.stepper.internal.feedback;
1818

19+
import android.support.annotation.FloatRange;
1920
import android.support.annotation.NonNull;
2021
import android.support.annotation.RestrictTo;
2122
import android.view.View;
22-
import android.widget.ProgressBar;
2323

2424
import com.stepstone.stepper.R;
2525
import com.stepstone.stepper.StepperLayout;
2626

2727
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
28-
import static com.stepstone.stepper.internal.util.AnimationUtil.ALPHA_HALF;
2928
import static com.stepstone.stepper.internal.util.AnimationUtil.ALPHA_OPAQUE;
3029

3130
/**
32-
* Feedback stepper type which displays a progress bar on top of the steps' content and partially fades the content out.
31+
* Feedback stepper type which partially fades the content out.
3332
*/
3433
@RestrictTo(LIBRARY)
35-
public class ContentStepperFeedbackType implements StepperFeedbackType {
34+
public class ContentFadeStepperFeedbackType implements StepperFeedbackType {
3635

36+
@NonNull
3737
private final View mPager;
3838

39-
private final ProgressBar mPagerProgressBar;
39+
@FloatRange(from = 0.0f, to = 1.0f)
40+
private final float mFadeOutAlpha;
4041

41-
public ContentStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
42+
public ContentFadeStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
4243
mPager = stepperLayout.findViewById(R.id.ms_stepPager);
43-
mPagerProgressBar = (ProgressBar) stepperLayout.findViewById(R.id.stepPagerProgressBar);
44+
mFadeOutAlpha = stepperLayout.getContentFadeAlpha();
4445
}
4546

4647
@Override
4748
public void showProgress(@NonNull String progressMessage) {
48-
mPagerProgressBar.setVisibility(View.VISIBLE);
4949
mPager.animate()
50-
.alpha(ALPHA_HALF)
50+
.alpha(mFadeOutAlpha)
5151
.setDuration(PROGRESS_ANIMATION_DURATION);
5252
}
5353

5454
@Override
5555
public void hideProgress() {
56-
mPagerProgressBar.setVisibility(View.GONE);
5756
mPager.animate()
5857
.alpha(ALPHA_OPAQUE)
5958
.setDuration(PROGRESS_ANIMATION_DURATION);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2017 StepStone Services
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.stepstone.stepper.internal.feedback;
18+
19+
import android.support.annotation.NonNull;
20+
import android.support.annotation.RestrictTo;
21+
import android.view.View;
22+
23+
import com.stepstone.stepper.R;
24+
import com.stepstone.stepper.StepperLayout;
25+
26+
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
27+
import static com.stepstone.stepper.internal.util.AnimationUtil.ALPHA_INVISIBLE;
28+
import static com.stepstone.stepper.internal.util.AnimationUtil.ALPHA_OPAQUE;
29+
30+
/**
31+
* Feedback stepper type which shows a dimmed overlay over the content.
32+
*/
33+
@RestrictTo(LIBRARY)
34+
public class ContentOverlayStepperFeedbackType implements StepperFeedbackType {
35+
36+
@NonNull
37+
private final View mOverlayView;
38+
39+
public ContentOverlayStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
40+
mOverlayView = stepperLayout.findViewById(R.id.ms_stepPagerOverlay);
41+
mOverlayView.setVisibility(View.VISIBLE);
42+
mOverlayView.setAlpha(ALPHA_INVISIBLE);
43+
final int contentOverlayBackground = stepperLayout.getContentOverlayBackground();
44+
if (contentOverlayBackground != 0) {
45+
mOverlayView.setBackgroundResource(contentOverlayBackground);
46+
}
47+
}
48+
49+
@Override
50+
public void showProgress(@NonNull String progressMessage) {
51+
mOverlayView.animate()
52+
.alpha(ALPHA_OPAQUE)
53+
.setDuration(PROGRESS_ANIMATION_DURATION);
54+
}
55+
56+
@Override
57+
public void hideProgress() {
58+
mOverlayView.animate()
59+
.alpha(ALPHA_INVISIBLE)
60+
.setDuration(PROGRESS_ANIMATION_DURATION);
61+
}
62+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright 2017 StepStone Services
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.stepstone.stepper.internal.feedback;
18+
19+
import android.support.annotation.NonNull;
20+
import android.support.annotation.RestrictTo;
21+
import android.view.View;
22+
import android.widget.ProgressBar;
23+
24+
import com.stepstone.stepper.R;
25+
import com.stepstone.stepper.StepperLayout;
26+
27+
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
28+
29+
/**
30+
* Feedback stepper type which displays a progress bar on top of the steps' content.
31+
*/
32+
@RestrictTo(LIBRARY)
33+
public class ContentProgressStepperFeedbackType implements StepperFeedbackType {
34+
35+
@NonNull
36+
private final ProgressBar mPagerProgressBar;
37+
38+
public ContentProgressStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
39+
mPagerProgressBar = (ProgressBar) stepperLayout.findViewById(R.id.ms_stepPagerProgressBar);
40+
}
41+
42+
@Override
43+
public void showProgress(@NonNull String progressMessage) {
44+
mPagerProgressBar.setVisibility(View.VISIBLE);
45+
}
46+
47+
@Override
48+
public void hideProgress() {
49+
mPagerProgressBar.setVisibility(View.GONE);
50+
}
51+
}

material-stepper/src/main/java/com/stepstone/stepper/internal/feedback/DisabledBottomNavigationStepperFeedbackType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
2525

2626
/**
27-
* Feedback stepper type which disabled the buttons in the bottom navigation when an operation is in progress.
27+
* Feedback stepper type which disables the buttons in the bottom navigation when an operation is in progress.
2828
*/
2929
@RestrictTo(LIBRARY)
3030
public class DisabledBottomNavigationStepperFeedbackType implements StepperFeedbackType {
3131

32+
@NonNull
3233
private StepperLayout mStepperLayout;
3334

3435
public DisabledBottomNavigationStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright 2017 StepStone Services
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.stepstone.stepper.internal.feedback;
18+
19+
import android.support.annotation.NonNull;
20+
import android.support.annotation.RestrictTo;
21+
22+
import com.stepstone.stepper.R;
23+
import com.stepstone.stepper.StepperLayout;
24+
import com.stepstone.stepper.internal.widget.StepViewPager;
25+
26+
import static android.support.annotation.RestrictTo.Scope.LIBRARY;
27+
28+
/**
29+
* Feedback stepper type which intercepts touch events on the steps' content and ignores them.
30+
*/
31+
@RestrictTo(LIBRARY)
32+
public class DisabledContentInteractionStepperFeedbackType implements StepperFeedbackType {
33+
34+
@NonNull
35+
private final StepViewPager mStepPager;
36+
37+
public DisabledContentInteractionStepperFeedbackType(@NonNull StepperLayout stepperLayout) {
38+
mStepPager = (StepViewPager) stepperLayout.findViewById(R.id.ms_stepPager);
39+
}
40+
41+
@Override
42+
public void showProgress(@NonNull String progressMessage) {
43+
setContentInteractionEnabled(false);
44+
}
45+
46+
@Override
47+
public void hideProgress() {
48+
setContentInteractionEnabled(true);
49+
}
50+
51+
private void setContentInteractionEnabled(boolean enabled) {
52+
mStepPager.setBlockTouchEventsFromChildrenEnabled(!enabled);
53+
}
54+
55+
}

material-stepper/src/main/java/com/stepstone/stepper/internal/feedback/StepperFeedbackType.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,35 @@ public interface StepperFeedbackType {
2424
int TABS = 1 << 1;
2525

2626
/**
27-
* Shows a progress bar on top of the steps' content and partially fades the content out during operation.
28-
* @see ContentStepperFeedbackType
27+
* Shows a progress bar on top of the steps' content.
28+
* @see ContentProgressStepperFeedbackType
2929
*/
30-
int CONTENT = 1 << 2;
30+
int CONTENT_PROGRESS = 1 << 2;
3131

3232
/**
3333
* Disables the buttons in the bottom navigation during operation.
3434
* @see DisabledBottomNavigationStepperFeedbackType
3535
*/
3636
int DISABLED_BOTTOM_NAVIGATION = 1 << 3;
3737

38+
/**
39+
* Disables content interaction during operation i.e. stops step views from receiving touch events.
40+
* @see DisabledContentInteractionStepperFeedbackType
41+
*/
42+
int DISABLED_CONTENT_INTERACTION = 1 << 4;
43+
44+
/**
45+
* Partially fades the content out during operation.
46+
* @see ContentFadeStepperFeedbackType
47+
*/
48+
int CONTENT_FADE = 1 << 5;
49+
50+
/**
51+
* Shows a dimmed overlay over the content during operation.
52+
* @see ContentOverlayStepperFeedbackType
53+
*/
54+
int CONTENT_OVERLAY = 1 << 6;
55+
3856
int PROGRESS_ANIMATION_DURATION = 200;
3957

4058
/**

0 commit comments

Comments
 (0)