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.
compile 'com.stepstone.stepper:material-stepper:2.1.0'
- 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
<?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"
android:orientation="vertical"
app:ms_stepperType="progress_bar" />
For a complete list of StepperLayout attributes see [StepperLayout attributes](#StepperLayout attributes).
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
}
}
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 Fragment 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();
}
}
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));
}
}
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();
}
}
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:
-
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>
-
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" />
-
Toggle the state in code
mStepperLayout.setNextButtonVerificationFailed(!enabled); mStepperLayout.setCompleteButtonVerificationFailed(!enabled);
If the user wants to e.g. save something in the database or make a network call on a separate Thread after clicking on the Next button
he can perform these operations and then invoke the goToNextStep()
method of the StepperLayout.OnNextClickedCallback
in the current Step.
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
.
//...
@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 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 Back/Next button labels per step
Sometimes you might want to have different labels on the Next 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.
<p><img src ="./gifs/different-next-buttons.gif" width="360" height="640"/></p>
In such case you need to override the `getViewModel(int)` method from the `StepAdapter` e.g.
```java
@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
.setNextButtonLabel("This way")
.setBackButtonLabel("Go to first");
break;
case 1:
builder
.setNextButtonLabel(R.string.go_to_summary)
.setBackButtonLabel("Go to first");
break;
case 2:
builder.setBackButtonLabel("Go back");
break;
default:
throw new IllegalArgumentException("Unsupported position: " + position);
}
return builder.create();
}
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>
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.
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.
For other examples, e.g. persisting state on rotation, displaying errors, changing whether the user can go to the next step, etc. check out the sample app.
Attribute name | Format | Description |
---|---|---|
ms_stepperType | one of dots , progress_bar or tabs |
REQUIRED: Type of the stepper |
ms_backButtonColor | color or reference | BACK button's text color |
ms_nextButtonColor | color or reference | NEXT button's text color |
ms_completeButtonColor | color or reference | COMPLETE button's text color |
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_showErrorState | boolean | Flag indicating whether to show the error state. Only available with 'tabs' type. False by default. |
ms_showErrorStateOnBack | boolean | Flag indicating whether to keep showing the error state when user moves back. Only available with 'tabs' type. False by default. |
- support for non-linear steppers
- support for non-editable steppers
- support for Alternative labels in the horizontal stepper
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.