-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
Use case
I'm working on a project that is using the Stepper widget along with Step class.
Click to see full size
The problem is that we cannot customize the icon since it's hardcoded here:
flutter/packages/flutter/lib/src/material/stepper.dart
Lines 381 to 398 in 980b3c5
| style: isDarkActive ? _kStepStyle.copyWith(color: Colors.black87) : _kStepStyle, | |
| ); | |
| case StepState.editing: | |
| return Icon( | |
| Icons.edit, | |
| color: isDarkActive ? _kCircleActiveDark : _kCircleActiveLight, | |
| size: 18.0, | |
| ); | |
| case StepState.complete: | |
| return Icon( | |
| Icons.check, | |
| color: isDarkActive ? _kCircleActiveDark : _kCircleActiveLight, | |
| size: 18.0, | |
| ); | |
| case StepState.error: | |
| return const Text('!', style: _kStepStyle); | |
| } | |
| } |
This issue was already raised here #57236 before but no proposal was provided.
Proposal
There are several ways to include this use case (custom Stepper icon), the most simple one is to provide a callback parameter and let it build each icon.
// Add option to call an icon builder.
if (widget.stepIconBuilder != null) {
return widget.stepIconBuilder!(context, state);
}
// Current impl...
switch (state) {
...
}We can extend this approach and instead providing a callback param to build the icon child, we provide an callback API to build the icon itself:
flutter/packages/flutter/lib/src/material/stepper.dart
Lines 760 to 765 in 980b3c5
| children: <Widget>[ | |
| if (widget.steps[i].label != null) const SizedBox(height: 24.0,), | |
| Center(child: _buildIcon(i)), | |
| if (widget.steps[i].label != null) SizedBox(height : 24.0, child: _buildLabelText(i),), | |
| ], | |
| ), |
Adding an API to build the icon:
children: <Widget>[
SizedBox(
height: _isLabel() ? 104.0 : 72.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (widget.steps[i].label != null) const SizedBox(height: 24.0,),
if (widget.buildStepIcon != null)
widget.stepIconBuilder(context, i, /* state, maybe? */)
else
Center(child: _buildIcon(i)),
if (widget.steps[i].label != null) SizedBox(height : 24.0, child: _buildLabelText(i),),
],
),
),
// ...