android-material-stepper
介绍:
一个stepper控件,可以帮助你实现分步操作。
运行效果:
使用说明:
下载 (from JCenter)
compile 'com.stepstone.stepper:material-stepper:2.2.0'
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"
android:orientation="vertical"
app:ms_stepperType="progress_bar" />
StepperLayout的完整属性列表见 StepperLayout attributes.
创建step Fragment(s)
Step fragment必须继承android.support.v4.app.Fragment 并实现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
AbstractFragmentStepAdapter继承了FragmentPagerAdapter,但是你需要重写的是 createStep(int) 方法而不是getItem(int) 。
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();
}
}
在Activity中设置adapter
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));
}
}
在Activity中添加一个StepperListener(可选)
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();
}
}
Change Next/Complete button's text color when going to the next step should be disabled (optional)
可以在下一步的条件还没满足的时候改变next和Complete按钮的文字颜色。颜色要能够提示用户还不能进行下一步操作,看起来是被禁用的样子。
-
在res/color中创建一个新的颜色selector
<?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>
-
在布局文件中改变按钮的文字颜色
<?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" />
-
切换状态
mStepperLayout.setNextButtonVerificationFailed(!enabled); mStepperLayout.setCompleteButtonVerificationFailed(!enabled);
在下一步之前做IO操作(可选)
如果用户想在点击下一步之后开启一个线程做网络请求或者数据库保存方面的工作,可以执行这些操作并调用StepperLayout.OnNextClickedCallback的goToNextStep() 方法。当操作正在执行的时候,可以取消然后触发StepperLayout.OnBackClickedCallback的onBackClicked() 方法。
此时fragment必须实现BlockingStep而不是Step。同时还要确保goToNextStep() 是在主线程调用的。
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 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();
}
}
改变每一步中 Back/Next 按钮的文字
有时你可能希望在不同的步骤上 Next/ Back按钮的文字是不同的。比如,在前面几步使用默认的文字,在完成的前一步显示'Summary' 。
这种情况下你需要重写StepAdapter的getViewModel(int) 方法。
@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();
}
设置stepper的统一样式
如果你的应用中有很多steppers你可能需要一个统一的样式。为此你需要在主题中设置ms_stepperStyle属性。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="ms_stepperStyle">@style/DotStepperStyle</item>
</style>
然后在XML中定义这个样式:
<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>
让第一步显示返回按钮
第一步的返回按钮默认是隐藏的。可以把ms_showBackButtonOnFirstStep属性设置为true改变这一行为:
<?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" />
要让这个按钮点击之后能收到返回你需要设置一个StepperListener,在 onReturn() 方法中写你自定义的返回逻辑,比如关闭Activity。
和View一起使用
前面的例子都是基于Fragment的,其实这个库也可以不依赖Fragments。使用AbstractStepAdapterinstead就行了(而不是AbstractFragmentStepAdapter)。如何和view一起使用请看sample。
自定义样式
基本的样式可以通过选择active 和 inactive step color来完成。有一些属性可以直接通过设置StepperLayout的属性来改变,比如底部导航按钮的背景颜色(见 StepperLayout attributes)。至于更高级的样式你可以使用ms_stepperLayoutTheme。
StepperLayout 属性
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_errorColor | color or reference | Error color in Tabs stepper |
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. |
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 样式属性
ms_stepperLayoutTheme属性的列表,负责定义StepperLayout的子view样式。
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_stepTabsScrollViewStyle | Used by ms_stepTabsScrollView in layout/ms_tabs_container |
ms_stepTabsInnerContainerStyle | Used by ms_stepTabsInnerContainer 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_stepTabErrorIndicatorStyle | Used by ms_stepErrorIndicator in layout/ms_step_tab |
ms_stepTabTitleStyle | Used by ms_stepTitle in layout/ms_step_tab |
ms_stepTabDividerStyle | Used by ms_stepDivider in layout/ms_step_tab |