Android Material Stepper


Source link: https://github.com/stepstone-tech/android-material-stepper

Android Material Stepper

This library allows to use Material steppers inside Android applications.

Quoting the documentation:

Steppers display progress through a sequence by breaking it up into multiple logical and numbered steps.

All of the code & features mentioned in Getting started and Advanced usage are showcased in the sample app. Moreover, you can find there other examples, e.g. how to persist state on rotation, display errors, change whether the user can go to the next step, etc. So please have a look!

Jump to section

Supported steppers

Mobile stepper with dots

  

Mobile stepper with progress bar

  

Mobile stepper without a progress indicator

Horizontal stepper

Supported features

  • color customisation of individual widgets inside of the stepper via View attributes or a style from a theme
  • custom texts of individual widgets inside of the stepper via View attributes or a style from a theme
  • embedding the stepper anywhere in the view hierarchy and changing the stepper type for various device configurations, e.g. phone/tablet, portrait/landscape
  • step validation
  • use with Fragments or Views
  • showing errors in tabs
  • showing stepper feedback for ongoing operations (see Stepper feedback)

Getting started

Download (from JCenter)

compile 'com.stepstone.stepper:material-stepper:4.3.1'

Note: This library adds a transitive dependency to AppCompat 25.4.0 which is the minimum Android Support library version compatible with the Stepper library.

Create layout in XML

<?xml version="1.0" encoding="utf-8"?> <com.stepstone.stepper.StepperLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/stepperLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:ms_stepperType="progress_bar" />

For a complete list of StepperLayout attributes see [StepperLayout attributes](#StepperLayout attributes).

Create step Fragment(s)

Step fragments must extend android.support.v4.app.Fragment and implement com.stepstone.stepper.Step

public class StepFragmentSample extends Fragment implements Step {

@Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.step, container, false);

 //initialize your UI

 return v;
  
}

@Override
  public VerificationError verifyStep() {

//return null if the user can go to the next step, create a new VerificationError instance otherwise

return null;
  
}

@Override
  public void onSelected() {

//update UI when selected
  
}

@Override
  public void onError(@NonNull VerificationError error) {

//handle error inside of the fragment, e.g. show error on EditText
  
}

}

Extend AbstractFragmentStepAdapter

AbstractFragmentStepAdapter extends FragmentPagerAdapter but instead of overriding the method getItem(int) you must override the createStep(int) method.

public static class MyStepperAdapter extends AbstractFragmentStepAdapter {

public MyStepperAdapter(FragmentManager fm, Context context) {

super(fm, context);

  
}

@Override
  public Step createStep(int position) {

final StepFragmentSample step = new StepFragmentSample();

Bundle b = new Bundle();

b.putInt(CURRENT_STEP_POSITION_KEY, position);

step.setArguments(b);

return step;
  
}

@Override
  public int getCount() {

return 3;
  
}

@NonNull
  @Override
  public StepViewModel getViewModel(@IntRange(from = 0) int position) {

//Override this method to set Step title for the Tabs, not necessary for other stepper types

return new StepViewModel.Builder(context)

  .setTitle(R.string.tab_title) //can be a CharSequence instead

  .create();

  
}
 
}
 

Set adapter in Activity

public class StepperActivity extends AppCompatActivity {

private StepperLayout mStepperLayout;

@Override
  protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mStepperLayout = (StepperLayout) findViewById(R.id.stepperLayout);

mStepperLayout.setAdapter(new MyStepperAdapter(getSupportFragmentManager(), this));

  
}
 
}

Add a StepperListener in the Activity (optional)

public class StepperActivity extends AppCompatActivity implements StepperLayout.StepperListener {

@Override
  protected void onCreate(Bundle savedInstanceState) {

//...

mStepperLayout.setListener(this);

  
}

@Override
  public void onCompleted(View completeButton) {

Toast.makeText(this, "onCompleted!", Toast.LENGTH_SHORT).show();

  
}

@Override
  public void onError(VerificationError verificationError) {

Toast.makeText(this, "onError! -> " + verificationError.getErrorMessage(), Toast.LENGTH_SHORT).show();

  
}

@Override
  public void onStepSelected(int newStepPosition) {

Toast.makeText(this, "onStepSelected! -> " + newStepPosition, Toast.LENGTH_SHORT).show();

  
}

@Override
  public void onReturn() {

finish();

  
}
  
}

Advanced usage

Making extra operations before going to the next step

After clicking on the Next button if the user wants to e.g.:

  • save something in the database
  • make a network call on a separate Thread
  • simply save the data from the current step to some other component or parent Activity (see 'Passing data between steps' in the sample app for more details)

he can perform these operations and then invoke the goToNextStep() method of the StepperLayout.OnNextClickedCallback in the current Step. If the user wants to perform these operations on the final step, when clicking on the Complete button, he needs to invoke the complete() method of the StepperLayout.OnCompleteClickedCallback. While operations are performed, and the user would like to go back you can cancel them and then invoke onBackClicked() method of the StepperLayout.OnBackClickedCallback.

To do so the fragment/view must implement BlockingStep instead of Step. Also, make sure that goToNextStep() and/or complete() get called on the main thread. Note: onNextClicked(StepperLayout.OnNextClickedCallback) and onCompleteClicked(StepperLayout.OnCompleteClickedCallback) methods get invoked after step verification. E.g.:

public class DelayedTransitionStepFragmentSample extends Fragment implements BlockingStep {

//...

@Override
  @UiThread
  public void onNextClicked(final StepperLayout.OnNextClickedCallback callback) {

new Handler().postDelayed(new Runnable() {

 @Override

 public void run() {

  callback.goToNextStep();

 
}

}
, 2000L);

  
}

@Override
  @UiThread
  public void onCompleteClicked(final StepperLayout.OnCompleteClickedCallback callback) {

new Handler().postDelayed(new Runnable() {

 @Override

 public void run() {

  callback.complete();

 
}

}
, 2000L);

  
}

@Override
  @UiThread
  public void onBackClicked(StepperLayout.OnBackClickedCallback callback) {

Toast.makeText(this.getContext(), "Your custom back action. Here you should cancel currently running operations", Toast.LENGTH_SHORT).show();

callback.goToPrevStep();

}
  
}

Changing button labels & compound drawables per step

Sometimes you might want to have different labels on the Next/Complete and/or Back navigation buttons on different steps e.g. use the default labels on the first few steps, but display 'Summary' just before the last page. You might also want to use your custom icons instead of the default navigation button compound drawables or not show the compound drawables for some of the buttons.

In such case you need to override the `getViewModel(int)` method from the `StepAdapter` e.g.
 @NonNull
  @Override
  public StepViewModel getViewModel(@IntRange(from = 0) int position) {

StepViewModel.Builder builder = new StepViewModel.Builder(context)

  .setTitle(R.string.tab_title);

switch (position) {

 case 0:

  builder

.setEndButtonLabel("This way")

.setBackButtonLabel("Cancel")

.setNextButtonEndDrawableResId(R.drawable.ms_forward_arrow)

.setBackButtonStartDrawableResId(StepViewModel.NULL_DRAWABLE);

  break;

 case 1:

  builder

.setEndButtonLabel(R.string.go_to_summary)

.setBackButtonLabel("Go to first")

.setBackButtonStartDrawableResId(R.drawable.ms_back_arrow);

  break;

 case 2:

  builder

.setBackButtonLabel("Go back")

.setEndButtonLabel("I'm done!");

  break;

 default:

  throw new IllegalArgumentException("Unsupported position: " + position);

}

return builder.create();

  
}

It is also possible to hide Back/Next/Complete buttons on each step if needed. To do so you need to call setBackButtonVisible(false) and/or setEndButtonVisible(false) on StepViewModel.Builder in your adapter.

Subtitles in tabs

You can set a subtitle for each step in stepper with tabs, e.g. to mark a step as optional. To do so you need to set the subtitle by calling StepViewModel.Builder#setSubtitle(int) or StepViewModel.Builder#setSubtitle(CharSequence) in your adapter's getViewModel method.

Custom styling

Basic styling can be done by choosing the active and inactive step colors. There are some additional properties which can be changed directly from StepperLayout's attributes e.g. the background of bottom navigation buttons (see StepperLayout attributes) For advanced styling you can use ms_stepperLayoutTheme StepperLayout's attribute and provide your custom style to be used. See 'Custom StepperLayout theme' in the sample app for an example.

Using same stepper styling across the application

If you have many steppers in your application in different activities/fragments you might want to set a common style in a theme. To do so, you need to set the ms_stepperStyle attribute in the theme, e.g.

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

...

<item name="ms_stepperStyle">@style/DotStepperStyle</item>
  </style>

and declare that style in the XML you keep your styles at, e.g.

 <style name="DotStepperStyle">

<item name="ms_stepperType">dots</item>

<item name="ms_activeStepColor">#FFFFFF</item>

<item name="ms_inactiveStepColor">#006867</item>

<item name="ms_bottomNavigationBackground">?attr/colorAccent</item>
  </style>

Showing a Back button on first step

By default if the user is on the first step then the Back button in the bottom navigation is hidden. This behaviour can be changed by setting ms_showBackButtonOnFirstStep to true, e.g.

 <?xml version="1.0" encoding="utf-8"?>
  <com.stepstone.stepper.StepperLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/stepperLayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:ms_showBackButtonOnFirstStep="true"

app:ms_stepperType="dots" />

To get a callback when this button was pressed you need set a StepperListener and write your own custom return logic in the onReturn() method to e.g. close the Activity.

Using Views instead of Fragments as Steps

It is possible to use this library without the need to rely on Fragments. To do so you need to use AbstractStepAdapter instead of AbstractFragmentStepAdapter. For an example of how to use it with views please see the sample app.

Showing an error on tabs if step verification failed

To show an error in the tabbed stepper if step verification fails you need to set ms_showErrorStateEnabled attribute to true.

If you want to keep the error displayed when going back to the previous step you need to also set ms_showErrorStateOnBackEnabled to true. If you want display an error message below the step title you need to set ms_showErrorMessageEnabled to true. The message set in VerificationError will be then displayed.

Stepper feedback

It is possible to show stepper feedback for ongoing operations (see Stepper feedback). To do so you firstly need to set ms_stepperFeedbackType to one or more of:

  • tabs - shows a progress message instead of the tabs during operation.
  • content_progress - shows a progress bar on top of the steps' content.
  • 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.
  • 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.
  • 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).
  • disabled_content_interaction - intercepts touch events on the steps' content and ignores them during operation.

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

After setting this to show the feedback you need to call StepperLayout#showProgress(@NonNull String progressMessage) and do hide the progress indicator you need to call StepperLayout#hideProgress().

E.g. In layout:

 <?xml version="1.0" encoding="utf-8"?>
  <com.stepstone.stepper.StepperLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/stepperLayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:ms_backButtonColor="@color/ms_disabling_button_text_color_selector"

app:ms_nextButtonColor="@color/ms_disabling_button_text_color_selector"

app:ms_completeButtonColor="@color/ms_disabling_button_text_color_selector"

app:ms_stepperType="tabs"

app:ms_stepperFeedbackType="tabs|content|disabled_bottom_navigation" />

and in BlockingStep:

public class StepperFeedbackStepFragment extends Fragment implements BlockingStep {

//...

@Override
  @UiThread
  public void onNextClicked(final StepperLayout.OnNextClickedCallback callback) {

callback.getStepperLayout().showProgress("Operation in progress, please wait...");

new Handler().postDelayed(new Runnable() {

 @Override

 public void run() {

  callback.goToNextStep();

  callback.getStepperLayout().hideProgress();

 
}

}
, 2000L);

  
}

//... 

Changing button text color when going to the next step should be disabled

It is possible to change the Next/Complete button's text color (together with right chevron's color) when all the criteria to go to the next step are not met. This color should indicate that the user cannot go to next step yet and look as if disabled. Clicking on the button will still perform the regular step verification. There is a custom state added since setting android:state_enabled to false in a color selector would disable the clicks and we want to have them so that we can show an info message for the user. In order to set that color:

  1. Create a new color selector in res/color
 <?xml version="1.0" encoding="utf-8"?>
  <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

<item app:state_verification_failed="true" android:color="#30BDBDBD"/>

<item android:color="@color/ms_white"/>
  </selector>
  1. Change button's (text) color in layout file
 <?xml version="1.0" encoding="utf-8"?>
  <com.stepstone.stepper.StepperLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/stepperLayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:ms_stepperType="dots"

app:ms_nextButtonColor="@color/ms_custom_button_text_color"

app:ms_completeButtonColor="@color/ms_custom_button_text_color" />
  1. Toggle the state in code
 mStepperLayout.setNextButtonVerificationFailed(!enabled);

  mStepperLayout.setCompleteButtonVerificationFailed(!enabled);

Hiding bottom navigation bar

Bottom navigation bar is shown by default. If in your UI you would like to hide the bottom navigation bar you can do that by either setting the ms_showBottomNavigation attribute in XML to false or by setting it programmatically by calling StepperLayout#setShowBottomNavigation(boolean) with false.

StepperLayout attributes

View attributes

A list of base StepperLayout attributes used for behaviour configuration & base UI configuration. For advanced styling please see StepperLayout style attributes.

Attribute name Format Description
ms_stepperType one of dots, progress_bar, tabs or none REQUIRED: Type of the stepper
ms_backButtonColor color or reference BACK button's text color, can be also set via StepperLayout#setBackButtonColor(int)/ StepperLayout#setBackButtonColor(ColorStateList)
ms_nextButtonColor color or reference NEXT button's text color, can be also set via StepperLayout#setNextButtonColor(int)/ StepperLayout#setNextButtonColor(ColorStateList)
ms_completeButtonColor color or reference COMPLETE button's text color, can be also set via StepperLayout#setCompleteButtonColor(int)/ StepperLayout#setCompleteButtonColor(ColorStateList)
ms_activeStepColor color or reference Active step's color
ms_inactiveStepColor color or reference Inactive step's color
ms_bottomNavigationBackground reference Background of the bottom navigation
ms_backButtonBackground reference BACK button's background
ms_nextButtonBackground reference NEXT button's background
ms_completeButtonBackground reference COMPLETE button's background
ms_backButtonText string or reference BACK button's text
ms_nextButtonText string or reference NEXT button's text
ms_completeButtonText string or reference COMPLETE button's text
ms_tabStepDividerWidth dimension or reference The width of the horizontal tab divider used in tabs stepper type
ms_showBackButtonOnFirstStep boolean Flag indicating if the Back (Previous step) button should be shown on the first step. False by default.
ms_errorColor color or reference Error color in Tabs stepper
ms_showErrorStateEnabled boolean Flag indicating whether to show the error state. Only applicable for 'tabs' type. False by default.
ms_showErrorStateOnBackEnabled boolean Flag indicating whether to keep showing the error state when user moves back. Only applicable for 'tabs' type. False by default.
ms_tabNavigationEnabled boolean Flag indicating whether step navigation is possible by clicking on the tabs directly. Only applicable for 'tabs' type. True by default.
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.
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.
ms_stepperFeedback_contentOverlayBackground reference Background to be used for the overlay on top of the content if content_overlay stepper feedback type is set.
ms_showBottomNavigation boolean Flag indicating if the Bottom Navigation bar should be shown on the layout. True by default.
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.

StepperLayout style attributes

A list of ms_stepperLayoutTheme attributes responsible for styling of StepperLayout's child views.

Attribute name Description
ms_bottomNavigationStyle Used by ms_bottomNavigation in layout/ms_stepper_layout
ms_tabsContainerStyle Used by ms_stepTabsContainer in layout/ms_stepper_layout
ms_backNavigationButtonStyle Used by ms_stepPrevButton in layout/ms_stepper_layout
ms_nextNavigationButtonStyle Used by ms_stepNextButton in layout/ms_stepper_layout
ms_completeNavigationButtonStyle Used by ms_stepCompleteButton in layout/ms_stepper_layout
ms_colorableProgressBarStyle Used by ms_stepProgressBar in layout/ms_stepper_layout
ms_stepPagerProgressBarStyle Used by ms_stepPagerProgressBar in layout/ms_stepper_layout
ms_stepPagerOverlayStyle Used by ms_stepPagerOverlay in layout/ms_stepper_layout
ms_stepTabsScrollViewStyle Used by ms_stepTabsScrollView in layout/ms_tabs_container
ms_stepTabsInnerContainerStyle Used by ms_stepTabsInnerContainer in layout/ms_tabs_container
ms_stepTabsProgressMessageStyle Used by ms_stepTabsProgressMessage in layout/ms_tabs_container
ms_stepTabContainerStyle Used in layout/ms_step_tab_container
ms_stepTabNumberStyle Used by ms_stepNumber in layout/ms_step_tab
ms_stepTabDoneIndicatorStyle Used by ms_stepDoneIndicator in layout/ms_step_tab
ms_stepTabIconBackgroundStyle Used by ms_stepIconBackground in layout/ms_step_tab
ms_stepTabTitleStyle Used by ms_stepTitle in layout/ms_step_tab
ms_stepTabSubtitleStyle Used by ms_stepSubtitle in layout/ms_step_tab
ms_stepTabDividerStyle Used by ms_stepDivider in layout/ms_step_tab

Changelog

See changelog

Espresso tests

If you wish to run Espresso tests on a screen containing a StepperLayout you might want to use espresso-material-stepper which contains useful Espresso actions and matchers such as clicking on navigation buttons & tabs. To do so add a Gradle dependency:

 androidTestCompile 'com.stepstone.stepper:espresso-material-stepper:X.X.X'

Please see the sample app which uses it in instrumentation tests for more details.

Contributing

All contributions are welcome and encouraged!

If you wish to contribute please create an issue first explaining the proposed changes.

Project is built on Circle CI on which we run static code analysis as well as unit & instrumentation tests to ensure that the latest changes don't break anything. To check if your changes pass execute:

./gradlew checkWithUiTests 

Or on a device below Marshmallow:

./gradlew checkWithUiTests -Ptest.integration.options.adbInstallOptions=-r 

License

Copyright 2016 StepStone Services

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Maintained by

Resources

Android screen or view recorder.

A easy and simple library to apply Gaussian blur on images.

Sometimes it's necessary to retrieve some information from a properties file that is not checked in as part of your repo for security reasons (keys, credentials, passwords, etc). Such properties need to end up in your application BuildConfig or in some resource file.

The library allows to format user input on the fly according to the provided mask and to extract valueable characters.

Provides a simple way to extend the default RecyclerView behaviour with support for headers, footers, empty view, DiffUtil and ArrayAdapter like methods.

Simple and pretty, powerful and flexible logger for android and java, can concurrently print the log to multiple target like Logcat, System.out and File, or even Server (or anywhere) if you like.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes