Reputation: 9692
I want to create this type of stepper in flutter
till now i have tried this two way
Widget get stepper =>
Container(
padding: EdgeInsets.all(15),
color: Colors.white,
child: ListView.builder(
itemCount: stepperLIst.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return IntrinsicHeight(
child: Container(
margin: const EdgeInsets.only(bottom: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Column(
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: [
Image.asset(stepperLIst[position].iconName),
SizedBox(height: 10),
CustomPaint(painter: LineDashedPainter(lineColor: Colors.grey))
],
),
SizedBox(width: 10),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
stepperLIst[position].tittle,
style: BaseStyles.textStyle.copyWith(fontFamily: BaseFonts.bold),
),
SizedBox(height: 10),
Text(
stepperLIst[position].value,
style: BaseStyles.textStyle,
)
],
),
)
]),
),
);
}));
And also using stack
Widget get stepper2 =>
Container(
padding: EdgeInsets.all(15),
color: Colors.white,
child: ListView.builder(
itemCount: stepperLIst.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return Stack(
children: <Widget>[
Positioned(
left: 0,
top: 0,
bottom: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.down,
children: [
Image.asset(stepperLIst[position].iconName),
SizedBox(height: 10),
CustomPaint(painter: LineDashedPainter(lineColor: Colors.grey))
],
), // replace with your image
),
Padding(
padding: const EdgeInsets.only(left: 40),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
stepperLIst[position].tittle,
style: BaseStyles.textStyle.copyWith(fontFamily: BaseFonts.bold),
),
SizedBox(height: 10),
Text(
stepperLIst[position].value,
style: BaseStyles.textStyle,
)
],
),
)
],
);
}));
Using above code I'm not getting exact output
can anybody help me to create this type of stepper
If need more information please do let me know. Thanks in advance. Your efforts will be appreciated.
Upvotes: 2
Views: 14415
Reputation: 1869
This is a late response but since I found this question unanswered, here is my solution. It is based on Flutter version 3+ but also works on Flutter 2+.
Row
/Column
WidgetsHere I use 2 rows
inside a column
and repeat them in a listview
. The VerticalDivider
widget is a straight line but you can use other methods such as CustomPaint
or Container
to create dotted lines or use libraries such as flutter_dash
Click here to see the practical solution demo on DartPad or reveal here
List<Map<String, dynamic>> userInfoList = [
{
'icon': const Icon(Icons.info, color: Colors.orange),
'title': 'About',
'content':
'\$ - American - Restuarant - Western Food\nLocally Resto with the one and only master recipe.\nIn this industry since 1988 - +1182 218 281',
},
{
'icon': const Icon(Icons.web, color: Colors.lightBlueAccent),
'title': 'Website',
'content': 'www.moscorestourant.com',
},
{
'icon': const Icon(Icons.location_on, color: Colors.pink),
'title': 'Location',
'content': '100 Peachtree Boston 30308',
},
{
'icon': const Icon(Icons.person, color: Colors.greenAccent),
'title': 'Contact Person',
'content': 'Jenny F.\[email protected]\n+ 999 999 999',
},
];
@override
Widget build(BuildContext context) {
return SafeArea(
child: Material(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: userInfoList.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext content, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
flex: 1,
child: userInfoList[index]['icon'],
),
Expanded(
flex: 10,
child: Text(
userInfoList[index]['title'],
maxLines: null,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
fontSize: 16.0,
),
),
),
],
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
const Expanded(
flex: 1,
child: VerticalDivider(
color: Colors.black,
thickness: 2.0,
),
),
Expanded(
flex: 10,
child: Text(
userInfoList[index]['content'],
maxLines: null,
),
),
],
),
),
],
),
);
},
),
),
),
);
Stepper
WidgetWhile the design is not exactly like yours, it is still a possible method that has a similar outcome.
stepIconBuilder
parameter of the Stepper()
widget to customise the icons.controlsBuilder
parameter of the Stepper()
widget to customise the 'next' and 'back' buttons to be shrunk.Click here to see the practical solution demo on DartPad or reveal here
List<Map<String, dynamic>> userInfoList = [
{
'icon': const Icon(Icons.info, color: Colors.orange),
'title': 'About',
'content':
'\$ - American - Restuarant - Western Food\nLocally Resto with the one and only master recipe.\nIn this industry since 1988 - +1182 218 281',
},
{
'icon': const Icon(Icons.web, color: Colors.lightBlueAccent),
'title': 'Website',
'content': 'www.moscorestourant.com',
},
{
'icon': const Icon(Icons.location_on, color: Colors.pink),
'title': 'Location',
'content': '100 Peachtree Boston 30308',
},
{
'icon': const Icon(Icons.person, color: Colors.greenAccent),
'title': 'Contact Person',
'content': 'Jenny F.\[email protected]\n+ 999 999 999',
},
];
@override
Widget build(BuildContext context) {
List<Step> stepsList = <Step>[
Step(
title: Text(userInfoList[0]['title']),
subtitle: Text(userInfoList[0]['content']),
content: Container(),
),
Step(
title: Text(userInfoList[1]['title']),
subtitle: Text(userInfoList[1]['content']),
content: Container(),
),
Step(
title: Text(userInfoList[2]['title']),
subtitle: Text(userInfoList[2]['content']),
content: Container(),
),
Step(
title: Text(userInfoList[3]['title']),
subtitle: Text(userInfoList[3]['content']),
content: Container(),
),
];
return SafeArea(
child: Material(
child: SingleChildScrollView(
child: Stepper(
steps: stepsList,
connectorColor: MaterialStateProperty.all(
Colors.black,
),
controlsBuilder: (BuildContext context, _) {
return const SizedBox.shrink();
},
stepIconBuilder: (int step, StepState state) {
return userInfoList[step]['icon'];
},
onStepTapped: (int index) {},
),
),
),
);
One of the main issue with this method is that the icons/steps have a background color that shares the same parameter (connectorColor
) as the vertical lines. This means to remove the Icon background using Colors.transparent
you would also lose the vertical lines.
Upvotes: 1
Reputation: 36
hope this package helps: another_stepper: ^1.0.4
AnotherStepper( stepperList: stepperData, stepperDirection: Axis.vertical, horizontalStepperHeight: 70, )
Upvotes: 1
Reputation: 1
I have idea ~
Stack(
children: [
Container(
margin: const EdgeInsets.only(left: 24, top:2),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
decoration: shown
? const BoxDecoration(
border: Border(
left: BorderSide(
width: 2,
color: Color(0xFFDDDDDD),
)))
: null,
child: Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Text(txt,
style: const TextStyle(
color: Color(0xFF1A1A1A),
fontWeight: FontWeight.w400,
fontSize: 13.0,
))),
),
const SizedBox(
height: 0,
width: 50,
child: Icon(Icons.circle, color: Color(0xFF222222), size: 16),
),
],
)
Demo https://img.alicdn.com/imgextra/i3/O1CN01TMfTZI1MFzdk535xL_!!6000000001406-0-tps-377-254.jpg
Upvotes: 0
Reputation: 281
I try to come close to your answer. I know it's too late to reply. but I am working on my issue and surfing the internet. I found your question and I get soln for that so, here it is...
import 'package:flutter/material.dart';
class CustomStepper extends StatelessWidget {
const CustomStepper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
margin: const EdgeInsets.only(left: 8, right: 5),
height: 18,
width: 18,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
border: Border.all(color: Colors.black)),
),
const Text("Title",style: TextStyle(fontWeight: FontWeight.bold)),
],
),
Container(
margin: const EdgeInsets.only(left: 17),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 5),
decoration: const BoxDecoration(
border: Border(
left: BorderSide(
color: Colors.red,
))),
child: const Text('SubTitle\nAbc'),
),
],
);
}
}
Upvotes: 1
Reputation: 8988
I have some resources to share with you. Just check those out and see if that works out for you. These are:
And if you really want those staggered lines in place of a single vertical lines between the icons in the Stepper, then check out the code of the library and make your own widget like that with some minimal changes.
Upvotes: 0