Flutter stepper with image and title above - flutter

I am trying to create a horizontal stepper that changes based on a status. It would need a title above, different image (preferably svg) inside the circle and changing color of the divider with the same thickness.
Im trying to achieve this
I tried different approach and other packages, and I cant seem to get to make this, maybe I'm doing something wrong.
Stepper has its title on the side and the circles are checks and numbers only.
IconStepper from im_stepper package only has icons for steps, and no titles, and only dots for the divider.
EnhanceStep from enhance_stepper package has the title below the the icon, and it doesn't have a circle. I tried editing the package and the icon is not aligned with the line anymore.
Custom Widget but it is all UI and no functionality on changing the selected, and changing the index changes the color of the step itself but not the ones before it. Also the text is not aligned along the center of the step, is just aligned using Row's MainAxisAlignment.spaceBetween,
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Testing4 extends StatefulWidget {
const Testing4({Key? key}) : super(key: key);
#override
State<Testing4> createState() => _Testing4State();
}
class _Testing4State extends State<Testing4> {
final List<int> steps = [1, 2, 3];
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Center(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
for (var step in steps) Center(child: Text('STEPPER # $step'))
],
),
SizedBox(
width: MediaQuery.of(context).size.width,
height: kToolbarHeight,
child: Stack(
alignment: Alignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: MediaQuery.of(context).size.width / 3,
child: const Divider(
color: Colors.black,
thickness: 5,
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 3,
child: const Divider(
color: Colors.grey,
thickness: 5,
),
),
],
),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (var step in steps)
Column(
children: [
Stack(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
step == 2 ? Colors.black : Colors.grey,
),
padding: const EdgeInsets.all(10),
child: Center(
child: SvgPicture.asset("assets/check.svg"),
),
)
],
),
],
)
],
),
)
],
),
),
],
)),
);
}
}

In the end, this one worked for me
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CustomStepper extends StatelessWidget {
CustomStepper({
Key? key,
required int currentStep,
required this.steps,
}) : _curStep = currentStep,
assert(currentStep >= 0 == true && currentStep <= steps.length),
super(key: key);
final int _curStep;
final Color _activeColor = Colors.black;
final Color _inactiveColor = Colors.grey.shade300;
final double lineWidth = 5.0;
final List<Map<String, dynamic>> steps;
List<Widget> _iconViews() {
var list = <Widget>[];
steps.asMap().forEach((i, icon) {
Color circleColor =
(i == 0 || _curStep >= i) ? _activeColor : _inactiveColor;
Color lineColor = _curStep > i ? _activeColor : _inactiveColor;
list.add(
Container(
width: 55.0,
height: 55.0,
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: circleColor,
),
child: SvgPicture.asset(
icon['image'],
),
),
);
if (i != steps.length - 1) {
list.add(Expanded(
child: Container(
height: lineWidth,
color: lineColor,
)));
}
});
return list;
}
List<Widget> _titleViews() {
var list = <Widget>[];
steps.asMap().forEach((i, text) {
list.add(Text(text["title"], style: TextStyle(color: _activeColor)));
});
return list;
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: _titleViews(),
),
const SizedBox(
height: 10,
),
Row(
children: _iconViews(),
),
],
);
}
}

Related

How can I add some widgets to the position of siblings in the row at Flutter

I'm trying to make a discrete progress indicator similar to percent indicator but in a discrete manner.
And I wanna add some guide widget or arrow at the position of the current progress position something like images. (It is not actually implemented, it is a view of widget inspector, but I wanna get the result of that image, top or bottom of the row.)
But, the problem is, how can I get the position of the child widget of the row and add some stacked widget to that?
class LinearDiscreteIndicator extends StatelessWidget {
final int numTotal;
final int numCurrent;
final double? width;
final double lineHeight;
final double margin;
final Color fillColor;
final Color emptyColor;
final Radius barRadious;
final MainAxisAlignment alignment;
final Widget? progressWidget;
const LinearDiscreteIndicator({
Key? key,
required this.numTotal,
required this.numCurrent,
this.width,
required this.lineHeight,
this.margin = 2,
this.fillColor = Colors.blue,
this.emptyColor = Colors.grey,
this.barRadious = const Radius.circular(2),
this.alignment = MainAxisAlignment.start,
this.progressWidget,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(
height: lineHeight,
width: width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: alignment,
children: List.generate(numTotal, (index) => index)
.map(
(e) => Expanded(
child: Padding(
padding: EdgeInsets.only(
right: e == (numTotal - 1) ? 0 : margin,
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(barRadious),
color: e > numCurrent ? emptyColor : fillColor,
),
),
),
),
)
.toList(),
),
),
],
);
}
}
This is my current widget class code, but I'm not sure how can I enable a tooltip-like widget at the position of the current progress.
var numCurrent = 10;
var numTotal = 30;
var itemWidth = (MediaQuery.of(context).size.width / numTotal);
double containerWidth = 80;
var positionLeft = ((itemWidth) * (numCurrent + 1)) - (containerWidth / 2);
return Scaffold(
appBar: AppBar(),
backgroundColor: theme.colorScheme.background,
body: SingleChildScrollView(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: Stack(
children: [
Positioned(
left: positionLeft,
top: 10,
child: Container(
child: Stack(
children: const [
Align(alignment: Alignment.topCenter, child: Text("Container")),
Align(
alignment: Alignment.bottomCenter,
child: Icon(
Icons.arrow_drop_down_sharp,
size: 24,
)),
],
),
width: containerWidth,
height: 30,
color: Colors.red,
),
),
Positioned(
bottom: 0,
child: LinearDiscreteIndicator(
numCurrent: numCurrent,
numTotal: numTotal,
lineHeight: 4,
width: MediaQuery.of(context).size.width,
),
),
],
),
),
],
),
),
);

How to remove padding of MaterialBanner?

I want to remove the following blue padding from MaterialBanner widget, but it doesn't seem to be customizable. I want to insert an image in the red region.
I looked into MaterialBanner for using across Scaffold widgets because ScaffoldMessenger doesn't allow me to insert widgets other than MaterialBanner.
Is there any suggestion?
dartpad.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Scaffold(body: JustBanner())));
}
class JustBanner extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _JustBannerState();
}
}
class _JustBannerState extends State<JustBanner> {
#override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () {
final messenger = ScaffoldMessenger.of(context);
messenger.clearMaterialBanners();
messenger.showMaterialBanner(MaterialBanner(
padding: EdgeInsets.zero,
leadingPadding: EdgeInsets.zero,
leading: const SizedBox.shrink(),
backgroundColor: Colors.blue,
content: Container(
color: Colors.red,
width: 200,
height: 50,
),
actions: const [SizedBox.shrink()]));
},
child: const Text('Banner')),
],
);
}
}
Container(
width: MediaQuery.of(context).size.width,
child: MaterialBanner(
content: Text('Hello'),
actions: [
Icon(Icons.add),
],
),
),
Its no possible without copy and re-create the class, buttonBar always appear:
final Widget buttonBar = Container( // <-- problematic widget
alignment: AlignmentDirectional.centerEnd,
constraints: const BoxConstraints(minHeight: 52.0),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: OverflowBar(
overflowAlignment: widget.overflowAlignment,
spacing: 8,
children: widget.actions,
),
);
final double elevation = widget.elevation ?? bannerTheme.elevation ?? 0.0;
final Color backgroundColor = widget.backgroundColor
?? bannerTheme.backgroundColor
?? theme.colorScheme.surface;
final TextStyle? textStyle = widget.contentTextStyle
?? bannerTheme.contentTextStyle
?? theme.textTheme.bodyText2;
Widget materialBanner = Container(
margin: EdgeInsets.only(bottom: elevation > 0 ? 10.0 : 0.0),
child: Material(
elevation: elevation,
color: backgroundColor,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: padding,
child: Row(
children: <Widget>[
if (widget.leading != null)
Padding(
padding: leadingPadding,
child: widget.leading,
),
Expanded(
child: DefaultTextStyle(
style: textStyle!,
child: widget.content,
),
),
if (isSingleRow)
buttonBar, // <----- here
],
),
),
if (!isSingleRow)
buttonBar, // <----- here
if (elevation == 0)
const Divider(height: 0),
],
),
),
);

Flutter - Flexible with column inside doesn't take max column height

I'm having problems with flex widget with a column inside where the children have a fixed height (constrained to min and max).
I have to build a screen with a column with many rows as children and each row has some column children and this column has widgets with restricted height.
I want each row to fit the maximum height of the inner column and at the same time all rows to fit the full height of the screen.
I mean, I want the children height has priority over his parent.
EDIT: I attached an image and the code to see the problem.
class SecheduleDatatable extends StatelessWidget {
final DateTime initDate;
final int dayTreshold;
final List<ActivityItem> items;
final bool buildHeaders;
SecheduleDatatable({
required this.items,
required this.initDate,
required this.dayTreshold,
this.buildHeaders = false,
});
final double spaceBetween = 64;
final double leftPadding = 32;
double minItemHeight = 100;
double maxItemHeight = 150;
double fontSize = 45;
double headerHeight = 120;
void _initSizes(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
if (screenWidth > 4000) {
fontSize = 100;
minItemHeight = 0;
maxItemHeight = 180;
headerHeight = 180;
} else if (screenWidth > 1920) {
fontSize = 45;
minItemHeight = 60;
maxItemHeight = 120;
headerHeight = 120;
} else {
fontSize = 25;
minItemHeight = 0;
maxItemHeight = 80;
headerHeight = 80;
}
}
#override
Widget build(BuildContext context) {
_initSizes(context);
return Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(child: _createColumns()),
..._createRows(),
],
);
}
bool hasToExpand(String time) {
final days = _createDays(true);
days.addAll(_createDays(false));
final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);
for (DateTime date in days) {
final tempItems = groupedByTimeSort[time]
?.where((element) => element.date.getInitDay() == date.getInitDay())
.toList();
if (tempItems != null && tempItems.length > 1) return false;
}
return true;
}
Widget _createColumns() {
final days = _createDays(true);
days.addAll(_createDays(false));
return IntrinsicHeight(
child: Row(
children: [
Expanded(
child: Row(
children: [
Expanded(child: _clock()),
Expanded(flex: 3, child: _header(days[0].formatHeaderDate())),
Expanded(flex: 3, child: _header(days[1].formatHeaderDate())),
],
)),
/* Spacer(
flex: 1,
), */
Expanded(
child: Row(
children: [
Expanded(child: Container()),
Expanded(flex: 4, child: _header(days[2].formatHeaderDate())),
Expanded(flex: 4, child: _header(days[3].formatHeaderDate())),
Expanded(child: Container())
],
)),
],
),
);
}
List<Widget> _createRows() {
final days = _createDays(true);
days.addAll(_createDays(false));
final groupedByTimeSort = items.groupBy((p0) => p0.dateFormated);
Widget _getItemByDate(String time, DateTime date) {
final maybeItems = groupedByTimeSort[time]
?.where((element) => element.date.getInitDay() == date.getInitDay());
if (maybeItems != null) {
return Column(
mainAxisSize: MainAxisSize.min,
children: maybeItems
.map((e) => hasToExpand(time)
? Flexible(child: _item(e, kSpacing / 2))
: Flexible(child: _item(e, 0)))
.toList());
} else {
return Container();
}
}
Widget _getItem(String time, int pos, int flex) {
return Expanded(flex: flex, child: IntrinsicHeight(child: _getItemByDate(time, days[pos])));
}
final rows = groupedByTimeSort.keys.map((time) {
final row = Flexible(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: _hour(time)),
_getItem(time, 0, 3),
_getItem(time, 1, 3),
],
),
)),
Expanded(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: Container()),
_getItem(time, 2, 4),
_getItem(time, 3, 4),
Expanded(child: Container()),
],
),
))
],
)));
/* final row = IntrinsicHeight(
child: Row(children: [
Expanded(child: _hour(time)),
...days.map((date) => Expanded(flex: 3, child: _getItemByDate(time, date))).toList()
])); */
return row;
}).toList();
return rows;
}
Widget _item(ActivityItem item, double spacing) {
return Container(
width: double.infinity,
margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
padding: EdgeInsets.all(spacing),
decoration: BoxDecoration(
color: item.activityModel!.color, borderRadius: BorderRadius.circular(15)),
child: Center(
child: Text(
item.activityModel!.getTitle(),
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
));
}
Widget _emptyItem() {
return Container(
// constraints: BoxConstraints(minHeight: minItemHeight, maxHeight: maxItemHeight),
width: double.infinity,
margin: EdgeInsets.symmetric(vertical: 1),
padding: EdgeInsets.all(kSpacing / 2),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
"",
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
));
}
Widget _clock() {
return Container(
padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
child: FittedBox(
fit: BoxFit.contain,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
FeatherIcons.clock,
),
),
),
);
}
Widget _hour(String time) {
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.symmetric(horizontal: kSpacing, vertical: 4),
decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
child: Align(
alignment: Alignment.topCenter,
child: FittedBox(
fit: BoxFit.contain,
child: Text(
time,
style: TextStyle(color: Colors.white, fontSize: fontSize, fontWeight: FontWeight.bold),
),
),
),
);
}
Widget _header(String text) {
return Container(
height: headerHeight,
margin: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
padding: EdgeInsets.all(kSpacing / 2),
decoration: BoxDecoration(color: Colors.black54, borderRadius: BorderRadius.circular(15)),
child: Align(
alignment: Alignment.center,
child: FittedBox(
child: Text(
text,
textAlign: TextAlign.center,
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: fontSize),
),
),
));
}
List<DateTime> _createDays(bool first) {
final days = first ? [initDate] : [initDate.add(Duration(days: dayTreshold ~/ 2))];
for (var i = first ? 1 : dayTreshold ~/ 2;
i < (first ? dayTreshold ~/ 2 : dayTreshold - 1);
i++) {
days.add(days.last.add(Duration(days: 1)));
}
return days;
}
}
I want that the parent row take height of column child. Notice the rows are flexible to fit responsiveness to screen changes.
So really, in summarize, I want the rows are responsiveness but its inner columns get max height.
Sorry is not easy to explain it.
I added singlechildscrollview and I set the height of the container for the column items at 320 for four items of 80.
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
#override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
scrollBehavior: MyCustomScrollBehavior(),
debugShowCheckedModeBanner:false,
home: Test_Flexible(),
);
}
}
class Test_Flexible extends StatefulWidget {
Test_Flexible({Key? key}) : super(key: key);
#override
State<Test_Flexible> createState() => _Test_FlexibleState();
}
class _Test_FlexibleState extends State<Test_Flexible> {
#override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text("Test Flexible"),) ,body:
SingleChildScrollView(child:
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Container(
height: 100,
color: Colors.orange,
)),
Expanded(
flex: 3,
child: Container(
height: 320,
color: Colors.blue,
child:(Column(children:[
Flexible(
child: Container(
height: 80,
color: Colors.purple,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.green,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.yellow,
),
),
Flexible(
child: Container(
height: 80,
color: Colors.pink,
),
),
]))
)),
Expanded(
flex: 3,
child: Container(
height: 100,
color: Colors.blueGrey,
)),
],)
])
,));
}
}

IconButton with Row

I would like, in this code, to put the IconButton in the top right corner of each ItemView. The ItemDescription and the ItemTitle centered at the top. I try to put them in the same Row but I can't get them to fit together, either the IconButton sticks to the text or it's in the middle.
I think it is easy but I didn't find a solution.
Here is the code:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../recyclerview/data.dart';
import 'package:watch/constants.dart';
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState(
);
}
}
class ListViewExampleState extends State<ListViewExample>{
List<Container> _buildListItemsFromItems(){
int index = 0;
return item.map((item){
var container = Container(
decoration: index % 2 == 0?
new BoxDecoration(color: const Color(0xFFFFFFFF)):
new BoxDecoration(
color: const Color(0xFFFAFAF5)
),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new CachedNetworkImage(
imageUrl: item.imageURL,
width: 200.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Expanded(
child: Row(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0 ),
child: Text(
item.title,
style: kItemTitle,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child:Text(
item.description,
style: kItemDescription,
),
),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: IconButton(
icon: Icon(Icons.favorite_border, color: Colors.black,),
iconSize: 24.0,
onPressed: null
),
)
],)
]),
),
]),
);
index = index + 1;
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Accueil', style: kAppBarStyle,),
backgroundColor: Colors.white,
elevation: 0,
),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}
Update : I have added a Spacer() and put all in the same row, and set CrossAxisAlignment to .center.
Put the Icon in the same row as the title and the description, with a Spacer() in between. That will then give you an overflow error, because the Spacer wants to take up as much space as physically possible, so with no restriction it goes on to infinity. To tell the Spacer that it is only allowed a finite amount of space, you have to set the mainAxisSize of the row to MainAxisSize.min
Here's the code, with a couple alterations so I was able to run it for myself.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: ListViewExample(),
);
}
}
class ListViewExample extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ListViewExampleState();
}
}
class ListViewExampleState extends State<ListViewExample> {
var items = [
Item(),
Item(),
Item(),
Item(),
];
List<Container> _buildListItemsFromItems() {
int index = 0;
return items.map(
(item) {
var container = Container(
decoration: index % 2 == 0
? new BoxDecoration(color: const Color(0xFFFFFFFF))
: new BoxDecoration(color: const Color(0xFFFAFAF5)),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(5.0),
child: new Container(
color: Colors.red,
width: 150.0,
height: 100.0,
),
),
Expanded(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: const EdgeInsets.only(bottom: 75.0),
child: Text(
item.title,
),
),
Container(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
item.description,
),
),
Spacer(),
GestureDetector(
child: Icon(
Icons.favorite_border,
size: 14,
color: Colors.black,
),
onTap: null,
),
],
),
),
],
),
);
index = index + 1;
return container;
},
).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Accueil'),
backgroundColor: Colors.white,
elevation: 0,
),
body: ListView(
children: _buildListItemsFromItems(),
),
);
}
}
class Item {
final String title;
final String description;
Item({this.title = 'FooTitle', this.description = 'BarDescription'});
}

No Material widget found in flutter

this screenshot of an No Material widget found
I try to add stars RateBar as below code but i got an error no material widget found.
what i need to do is that when i pressed on this flatButton i got a window to rate the order and submit this rate, how can i do that through my code below, or to inform me how to handle it
this is the widget of StarRating
import 'package:flutter/material.dart';
typedef void RatingChangeCallback(double rating);
class StarRating extends StatelessWidget {
final int starCount;
final double rating;
final RatingChangeCallback onRatingchanged;
final Color color;
StarRating({this.starCount=5, this.rating = .0, this.onRatingchanged, this.color});
Widget buildStar(BuildContext context, int index){
Icon icon;
if (index >= rating) {
icon = Icon(
Icons.star_border,
color: Theme.of(context).buttonColor
);
}
else if(index > rating - 1 && index < rating){
icon = Icon(
Icons.star_half,
color: Theme.of(context).primaryColor,
);
}else{
icon = Icon(
Icons.stars,
color: Theme.of(context).primaryColor,
);
}
return InkResponse(
onTap: onRatingchanged==null ? null : ()=> onRatingchanged(index+1.0),
child: icon,
);
}
#override
Widget build(BuildContext context) {
return Row(
children: List.generate(starCount, (index)=>buildStar(context, index)),
);
}
}
and this is the Screen to view the starBar:
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
class StarRatingScreen extends StatefulWidget {
static const routeName = '/starRating';
#override
_StarRatingScreenState createState() => _StarRatingScreenState();
}
class _StarRatingScreenState extends State<StarRatingScreen> {
double rating =3.5;
#override
Widget build(BuildContext context) {
return StarRating(
rating: rating,
onRatingchanged: (rating) => setState(() => this.rating = rating),
);
}
}
and in orderDetails screen through the flatbutton i need to show this Star Rate:
import 'package:felsaree/providers/order_provider.dart';
import 'package:felsaree/screens/star_rating_screen.dart';
import 'package:felsaree/widgets/star.rating.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class OrderDetails extends StatefulWidget {
static const routeName = '/orderDetails';
#override
_OrderDetailsState createState() => _OrderDetailsState();
}
class _OrderDetailsState extends State<OrderDetails> {
double rating = 3.5;
// Widget ratingChange(double rating){
// return StarRating(
// rating: rating,
// onRatingchanged: (rating)=>this.rating = rating,);
// }
#override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context).size.height;
final orderId = ModalRoute.of(context).settings.arguments as int;
final orderProvider = Provider.of<OrderProvider>(context, listen: false);
final order = orderProvider.findOrderById(orderId);
AppBar appBar = AppBar(title: Text(order.restaurantName),);
double _totalPrice =orderProvider.totalItemsPrice(order.orderItems);
bool _isAddress = orderProvider.checkUserAdress(order.address);
return Scaffold(
appBar: appBar,
body: Column(
children: <Widget>[
Card(
elevation: 4,
margin: EdgeInsets.all(10),
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Text(order.id.toString()),
SizedBox(height: 4,),
Text(order.restaurantName),
SizedBox(height: 4,),
Text(order.branchName),
SizedBox(height: 4,),
],
),
Column(
children: <Widget>[
Text(DateFormat.yMd().format(DateTime.now())),
SizedBox(height: 15,),
Text('InProgress'),
SizedBox(height: 15,)
],
)
],
),),
),
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey[100],
border: Border.all(width: 2, color: Colors.grey)
) ,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Price'),
Text('${_totalPrice}L.E'),
Text('Total: ${order.price}L.E')
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('PC Discount'),
Text('${order.discountValue}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('service Tax'),
Text('${order.serviceTax}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Delivery'),
Text('${order.delivery}L.E'),
Text(''),
],
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Vat'),
Text('${order.vatAmount}L.E'),
Text(''),
],
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(bottom: 20),
height: (mediaQuery
- appBar.preferredSize.height
- MediaQuery.of(context).padding.top)*0.30,
width: MediaQuery.of(context).size.width*.8,
child: ListView.builder(
itemCount: order.orderItems.length,
itemBuilder: (ctx, index){
final item = order.orderItems[index];
if(item.userComments == ''){
String userComment= 'no comment';
item.userComments = userComment;
}
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(item.image,),
),
title: Text(item.itemName),
subtitle: Text('count: ${item.count}'),
trailing: Text(item.userComments),
);
}
),
),
Container(
width: double.infinity,
margin: EdgeInsets.only(right: 10, left: 10),
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
color: Colors.grey[100],
child: Text('Delivery Address', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),
),
SizedBox(height: 8),
Container(
width: double.infinity,
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[100])
),
child: _isAddress? Text(order.address) : Text('no address found'),
),
FlatButton(
onPressed: ()=>Navigator.of(context).pushNamed(StarRatingScreen.routeName),
child: Text('Rate The Order', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),))
],
),
);
}
}
This can be fixed by ensuring that your main includes MaterialApp() and Scaffold() as ancestors of your widgets as so:
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: YourWidget(),
),
));
}
If, for whatever reason you don't want to use MaterialApp... you can use Material():
void main() {
runApp(
home: Scaffold(
appBar: AppBar(),
body: Material( child: YourWidget()),
),
);
}