For this example, I am using Cupertino icons, so if you want to use these, make sure the dependency is added in your projec’s pubspec.yaml file.
cupertino_icons: ^0.1.2
Create a widget for the step indicator view in a new file and declare the required variables.
class StepProgressView extends StatelessWidget { final double _width; final List<IconData> _icons; final List<String> _titles; final int _curStep; final Color _activeColor; final Color _inactiveColor = Colors.grey[100]; final double lineWidth = 4.0; }
Inside the class declare a constructor with the relevant parameters.
StepProgressView({Key key, @required List<IconData> icons, @required int curStep, List<String> titles, @required double width, @required Color color}) : _icons = icons, _titles = titles, _curStep = curStep, _width = width, _activeColor = color, assert(curStep > 0 == true && curStep <= icons.length), assert(width > 0), super(key: key);
Let us build the base layout of the widget now. Here we are creating a row for the icons, and a row for the titles are created only when the titles data are passed to the widget; otherwise, only icons will be shown.
Widget build (BuildContext context) { return Container( padding: EdgeInsets.only(top: 32.0, left: 24.0, right: 24.0,), width: this._width, child: Column( children: <Widget>[ Row( children: _iconViews(), ), SizedBox(height: 10,), if (_titles != null) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: _titleViews(), ), ], )); }
Now for the main view, we create a widget list for the icons row. We will loop through the icons list and create circular containers with icons and then a line.
List<Widget> _iconViews() { var list = <Widget>[]; _icons.asMap().forEach((i, icon) { //colors according to state var circleColor = (i == 0 || _curStep > i + 1) ? _activeColor : _inactiveColor; var lineColor = _curStep > i + 1 ? _activeColor : _inactiveColor; var iconColor = (i == 0 || _curStep > i + 1) ? _inactiveColor : _activeColor; list.add( //dot with icon view Container( width: 30.0, height: 30.0, padding: EdgeInsets.all(0), child: Icon(icon, color: iconColor,size: 15.0,), decoration: new BoxDecoration( color: circleColor, borderRadius: new BorderRadius.all(new Radius.circular(25.0)), border: new Border.all( color: _activeColor, width: 2.0, ), ), ), ); //line between icons if (i != _icons.length - 1) { list.add( Expanded( child: Container(height: lineWidth, color: lineColor,) ) ); } }); return list; }
Create the optional titles view.
List<Widget> _titleViews() { var list = <Widget>[]; _titles.asMap().forEach((i, text) { list.add(Text(text, style: TextStyle(color: _activeColor))); }); return list; }
That’s it. Let us create some icons for testing
const stepIcons = [Ionicons. ios_person, Ionicons.ios_home, Ionicons.ios_car, Ionicons.ios_card,Ionicons.ios_airplane]; final List<String> titles = ["step1", "step2", "step3","step4","step5"]; int _curStep = 2;
Finally, in your scaffold/column, add this:
StepProgressView(icons: stepIcons,width: MediaQuery.of(context).size.width,curStep: _curStep,color: Color(0xffe5649e),),
For updating the view, change _curStep and cal setState().
…
Leave A Comment