How to make Container height dynamic to fit ListView but to certain max height Flutter - flutter

I am trying to show ListView in a custom dialog window. What I want to make dialog box height dynamic according to ListView content but to certain max height. If the ListView content reaches specific height it should me scrollable.
This is my code:
class PeekTableDialog extends StatefulWidget {
Order order;
PeekTableDialog({required this.order});
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return PeekTableDialogState();
}
}
class PeekTableDialogState extends State<PeekTableDialog> {
final ScrollController controller = ScrollController();
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
void initState() {
super.initState();
}
Widget getExtras(Food fooditem) {
List<String> extras = [];
for (var extra in fooditem.extras) {
if (fooditem.extras.last == extra) {
extras.add(extra.name);
} else {
extras.add(extra.name + ', ');
}
}
return Wrap(
runSpacing: 2,
spacing: 2,
children: List.generate(
extras.length,
(index) {
return Text(
extras[index].toString(),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
fontStyle: FontStyle.italic,
),
);
},
),
);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return SizedBox(
width: MediaQuery.of(context).size.width * 0.50,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
color: Colors.grey[400],
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
alignment: Alignment.center,
child: Row(
children: [
Expanded(
child: Container(
alignment: Alignment.center,
child: Text(
widget.order.table!.name,
style: AppTextStyles().style2,
),
),
),
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
padding: EdgeInsets.zero,
icon: Icon(
Icons.close,
color: Colors.white,
size: 35,
),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
alignment: Alignment.center,
child: Text(
'\$' + widget.order.total,
style: TextStyle(
color: Colors.grey[800],
fontSize: 35,
fontWeight: FontWeight.w400,
),
),
),
SizedBox(
height: 15,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: Text(
'Qty',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
const SizedBox(
width: 10,
),
Expanded(
flex: 2,
child: Text(
'Item',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
child: Text(
'Price',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
child: Text(
'Disc.',
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
const Divider(
color: Colors.grey,
height: 1.5,
),
const SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.only(bottom: 30),
child: Scrollbar(
isAlwaysShown: true,
controller: controller,
thickness: 12,
showTrackOnHover: true,
child: ListView.separated(
itemCount: widget.order.cartItems.length,
controller: controller,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Container(
child: Row(
children: [
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
widget.order.cartItems[index].cartCount
.toString(),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.order.cartItems[index].name,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
const SizedBox(
height: 5,
),
getExtras(widget.order.cartItems[index]),
],
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
'\$' +
widget.order.cartItems[index].totalPrice
.toStringAsFixed(2),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
'\$' +
widget
.order.cartItems[index].newDiscPrice
.toStringAsFixed(2),
style: TextStyle(
color: Colors.grey[700],
fontSize: 14,
fontWeight: FontWeight.normal,
),
),
),
),
],
),
);
},
separatorBuilder: (context, index) {
return const SizedBox(height: 3);
},
),
),
),
],
),
),
],
),
);
}
}
Anyone help me please with this small issue.
Thanks in advance.

Well, It's pretty easy. All you have to do is to create a class like this :
class ExpandableText extends StatefulWidget {
ExpandableText(this.text, this.isLongText, {Key? key}) : super(key: key);
final String text;
bool isExpanded = false;
final bool isLongText;
#override
_ExpandableTextState createState() => _ExpandableTextState();
}
class _ExpandableTextState extends State<ExpandableText>
with TickerProviderStateMixin<ExpandableText> {
#override
void initState() {
if (widget.isLongText) {
setState(() {
widget.isExpanded = false;
});
} else {
widget.isExpanded = true;
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
AnimatedSize(
vsync: this,
duration: const Duration(milliseconds: 500),
child: ConstrainedBox(
constraints: widget.isExpanded
? const BoxConstraints(maxHeight: 250.0)
: const BoxConstraints(
maxHeight: 60.0,
),
child: SingleChildScrollView(
child: Text(
widget.text,
overflow: TextOverflow.fade,
),
),
),
),
widget.isExpanded
? ConstrainedBox(constraints: const BoxConstraints())
: TextButton(
style: const ButtonStyle(alignment: Alignment.topRight),
child: const Text(
'Expand..'
),
onPressed: () => setState(() => widget.isExpanded = true),
),
],
);
}
}
Just play with the maxHeight according to your needs. Call this class like this (inside your dialog window) :
ExpandableText(
dataToBeShown,
dataToBeShown.length > 250 ? true : false,
),

Related

flutter problem: dataColumn width issue and How to remove rowDivider from dataTable?

here i got width issue for data table and I also want every rowDivider will be remove,
and here I use animation, if you have any idea to improve animation then tell me.
here i got width issue for data table and I also want every rowDivider will be remove,
and here I use animation, if you have any idea to improve animation then tell me.
this is my full code
import 'package:bonanza_flutter/Constants/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double _height = 60.0;
bool _isExpanded = false;
Future<bool> _showList() async {
await Future.delayed(Duration(milliseconds: 300));
return true;
}
Future<bool> _showList1() async {
await Future.delayed(Duration(milliseconds: 10));
return true;
}
bool isOnPMS = true;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
),
body: SingleChildScrollView(
child: Column(
children: [
// imageSlider(),
pmsData(),
// advantages(),
// products(),
Container(
height: 20,
)
],
),
),
);
}
}
extension WidgetExtension on _HomePageState {
pmsData() {
return Container(
color: lightBlue,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(20.0),
child: Column( crossAxisAlignment: CrossAxisAlignment.start,children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"PMS",
style:
TextStyle(fontSize: tSize16, fontWeight: FontWeight.w500),
),
Row(
children: [
Container(
width: 22,
height: 22,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: skyBlue,
),
child: Icon(
Icons.arrow_back_ios_outlined,
color: Colors.white,
size: 17,
),
),
SizedBox(
width: 20,
),
Container(
width: 22,
height: 22,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: skyBlue,
),
child: Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.white,
size: 17,
),
),
],
)
],
),
SizedBox(
height: 8,
),
Text(
"ICICI Prudential PMS",
style: TextStyle(
fontSize: tSize14, fontWeight: FontWeight.w500, color: skyBlue),
),
SizedBox(
height: 12,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"\u{20B9} 50,00,000",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"ICICI Prudential PMS",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
SizedBox(
height: 14,
),
Text(
"\u{20B9} 2,02,993 (+4.06%)",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: green2Color),
),
SizedBox(
height: 5,
),
Text(
"Gains & Loss",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"\u{20B9} 52,02,993",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"Current Market Value",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
SizedBox(
height: 14,
),
Text(
"\u{20B9} 5",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: blackColor),
),
SizedBox(
height: 5,
),
Text(
"Total Holdings",
style: TextStyle(
fontSize: tSize11,
fontWeight: FontWeight.w500,
color: greyColor),
),
],
),
SizedBox(
width: 0,
)
],
),
],),
),
AnimatedContainer(
duration: Duration(milliseconds: 300),
height: _height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
// padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
children: [
_isExpanded
? SizedBox.shrink()
: FutureBuilder(
future: _showList1(),
/// will wait untill box animation completed
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SizedBox();
}
return Center(
child: Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 00, left: 70, right: 70),
child: SizedBox(
height: 25,
width: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: skyBlue,
shadowColor: Colors.transparent),
onPressed: () {
setState(() {
isOnPMS = !isOnPMS;
if (!_isExpanded) {
setState(() {
_height = 350;
_isExpanded = true;
});
} else {
setState(() {
_height = 50;
_isExpanded = false;
});
}
});
print(_isExpanded);
},
child: Text("View More"),
),
),
),
);
}),
_isExpanded
? FutureBuilder(
future: _showList(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SizedBox();
}
return Padding(
padding: const EdgeInsets.only(
top: 20.0, bottom: 00, left: 0, right: 0),
child: Column(
children: [
DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'#',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'STOCK',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'SECTOR',style: TextStyle(color: Colors.white),
),
),
DataColumn(
label: Text(
'WEIGHT',style: TextStyle(color: Colors.white),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('1')),
DataCell(Text('TCS')),
DataCell(Text('Global')),
DataCell(Text('11%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('2')),
DataCell(Text('DMART')),
DataCell(Text('Consumers')),
DataCell(Text('10%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('3')),
DataCell(Text('ICICIBANK')),
DataCell(Text('Financials')),
DataCell(Text('12%')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('4')),
DataCell(Text('RELIANCE')),
DataCell(Text('Industrial')),
DataCell(Text('13%')),
],
),
],
dividerThickness: 0,
headingRowColor:
MaterialStateColor.resolveWith(
(states) => greyColor),
headingRowHeight: 30,
),
Center(
child: Padding(
padding: const EdgeInsets.only(
top: 20.0,
bottom: 00,
left: 70,
right: 70),
child: SizedBox(
height: 25,
width: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: skyBlue,
shadowColor: Colors.transparent),
onPressed: () {
setState(() {
isOnPMS = !isOnPMS;
if (!_isExpanded) {
setState(() {
_height = 350;
_isExpanded = true;
});
} else {
setState(() {
_height = 50;
_isExpanded = false;
});
}
});
print(_isExpanded);
},
child: const Text('View Less'),
),
),
),
)
],
),
);
})
: SizedBox.shrink(),
],
),
)
],
),
);
}
}
I want like this dataDable.
this is my ui which I created.
Wrap DataTable with SingleChildScrollView and set scrollDirection to horizontal.
Use TableBorder to remove divider.

How to make dynamic listview in tabbar

I want to make here Listing of cicrleavater, and in that cicleavter size issue width not getting more than 20 ! i want to make listing like instagram stories...and each tap i want show same pages but data differnt and current circle avater border need to show yello color....! how to do that i show you my screen size issue top whre cicleavter size issue i want make dyanamic listview and show on border when i tapped on it it
class FolderPageTabBAr extends StatefulWidget {
#override
_FolderPageTabBArState createState() => _FolderPageTabBArState();
}
class _FolderPageTabBArState extends State<FolderPageTabBAr> {
List<Widget> pages = [
CampaignFolder(),
ShelfScreen(),
CampaignFolder(),
ShelfScreen(),
];
double Redius = 40.0;
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: pages.length,
initialIndex: 0,
child: Scaffold(
body: Stack(
children: <Widget>[
TabBarView(
children: pages,
),
Container(
margin: EdgeInsets.only(top: 110,left: 1),
child: SizedBox(
height: 80,
width: 500,
child: TabBar(
tabs: [
Column(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(Globals.PhotographerProf),
radius: 22,
),
Padding(
padding: const EdgeInsets.all(8.0),
child:Text(
'ALL',
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 12.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
)
],
),
Column(
children: <Widget>[
CircleAvatar(
radius: 22,
backgroundImage: NetworkImage(Globals.PhotographerProf),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
Globals.Buisnessname,
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 11.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
)
],
),
Column(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(Globals.PhotographerProf),
radius: 22,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Family",
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 10.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
)
],
),
Column(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(Globals.PhotographerProf),
radius: 22,
),
Padding(
padding: const EdgeInsets.all(8.0),
child:Text(
"Album",
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 9.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
)
],
),
],
unselectedLabelColor: Colors.orange,
labelColor: Colors.deepOrange,
indicatorColor: Colors.transparent,
),
)
),
],
),
),
);
}
}
To create multiple (dynamic) views that look similar use List View Builder
FULL Example:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MyClass {
final String url;
final int id;
MyClass(this.url, this.id);
}
class Foo extends StatefulWidget {
#override
State<StatefulWidget> createState() => FooState();
}
class FooState extends State<Foo> {
int selectedIndex = 0;
List<MyClass> items = [
MyClass('https://picsum.photos/250?image=9', 1),
MyClass('https://picsum.photos/250?image=10', 5),
MyClass('https://picsum.photos/250?image=11', 33)
];
#override
Widget build(BuildContext context) {
print("build");
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 90,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
child: getAvatarView(items[index], index == selectedIndex),
);
},
),
),
Text(
"here is my page for id ${items[selectedIndex].id}",
style: TextStyle(backgroundColor: Colors.black, color: Colors.red),
),
],
),
);
}
Widget getAvatarView(MyClass item, bool isSelected) {
return Container(
margin: isSelected ? const EdgeInsets.all(5.0) : null,
decoration: BoxDecoration(
border: isSelected ? Border.all(color: Colors.yellow) : null),
child: Column(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(item.url),
radius: 22,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'ALL',
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 12.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
)
],
),
);
}
}
To pass multiple attributes in an item (callback function, url for img,...) use a List of Custom classes.

Define Number of lists according with Number into Widget flutter

What I Have are number of orders received that has be shown into a tab into a widget in flutter according with this code:
class ShipmentTab extends StatefulWidget {
#override
_ShipmentTabState createState() => _ShipmentTabState();
}
class _ShipmentTabState extends State<ShipmentTab> {
**final shipmentNumber = "16";**
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
color: Color(0xfffeaf0d),
child: Container(
width: 40,
height: 40,
child: Icon(
Icons.local_shipping,
color: Colors.white,
),
),
),
),
Padding(
padding: const EdgeInsets.all(13),
child: Text(
shipmentNumber,
style: TextStyle(
color: Colors.white, fontSize: 35, fontWeight: FontWeight.bold),
),
),
],
);
}
}
as you can see variable is " shipmentNumber " that show "16"
below I have listview.builder and I need to add itemCount and this count has to be refered to the tab above "16"
this is the code of the list:
Container(
height: 400,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (ctx, int) {
return Card(
color: Color(0xFF1f2032),
elevation: 15,
child: Container(
width: 60,
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Card(
color: Color(0xfffeaf0d),
child: Container(
height: 40,
width: 40,
child: Icon(
Icons.local_shipping,
color: Colors.white,
size: 25,
)),
),
Text(
'Ref № $int',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
Text(
'Mario Rossi',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xfffeaf0d),
),
),
Text(
'Consegnato',
style: TextStyle(color: Colors.lightGreenAccent),
),
Icon(
Icons.share,
color: Colors.white,
)
],
),
),
);
},
),
),
],
);
}
}
ListView.builder has itemCount parameter. I notice shipmentNumber is in String so you can parse it to int. Also you need to remove the Container height wrapping your ListView
ListView.builder(
shrinkWrap: true,
itemCount: int.parse(shipmentNumber),
itemBuilder: (BuildContext context, int index) {
/** build your Item here **/
return BuiltItem();
},
)

SliverPersistentHeaderDelegate not fully collapsed

I'm having a hard time making a custom collapsing toolbar, attached below is a video for a normal case.
Then here's a screen record of the misbehavior, most of the time this happens.
Aside from the fact that the scrolling is not so snappy, you'll see in the second video that the sliver on the top is not completely collapsed.
Do you have any suggestion to improve the performance of the app and a solution for the bug?
here's my code inside the SliverPersistentHeaderDelegate
class DashboardHeaderPersistentDelegate extends SliverPersistentHeaderDelegate {
...
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
double shrinkPercentage = min(1, shrinkOffset / (maxExtent - minExtent));
double titleTopMargin = titleCollapsedTopPadding +
(titleExpandedTopPadding - titleCollapsedTopPadding) *
(1 - shrinkPercentage);
double titleFontSize = titleCollapsedFontSize +
(titleExpandedFontSize - titleCollapsedFontSize) *
(1 - shrinkPercentage);
double infoWidgetHeight = minExtent +
(maxExtent - minExtent) -
shrinkOffset -
titleTopMargin -
titleFontSize -
44;
double collapasedInfoOpacity = max(0, shrinkPercentage-.7)/.3;
return Material(
elevation: 0,
shadowColor: Colors.white,
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: titleFontSize,
alignment: Alignment.center,
child: Text(
'\$ 5329.05',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: titleFontSize,
fontWeight: FontWeight.w500),
),
margin: EdgeInsets.only(top: titleTopMargin, bottom: 8),
),
Container(
height: shrinkPercentage == 1 ? 20 : infoWidgetHeight,
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Opacity(
opacity: 1 - shrinkPercentage,
child: _buildInformationWidget(context),
),
Opacity(
opacity: collapasedInfoOpacity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: _buildCollapsedInformationWidget(),
),
)
],
),
)
],
),
),
);
}
Widget _buildInformationWidget(BuildContext context) => ClipRect(
child: OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
child: FittedBox(
fit: BoxFit.fitWidth,
alignment: Alignment.center,
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'AVAILABLE BALANCE',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.green[400]),
),
),
Text(
' I ',
style: TextStyle(fontSize: 20, color: Colors.black12),
),
Container(
width: 100,
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.red[400]),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 12, top: 12),
alignment: Alignment.centerLeft,
child: Text(
"CATEGORIES",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
),
Container(
height: 88,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
left: (index == 0) ? 24.0 : 8.0,
right: (index == categories.length - 1)
? 24.0
: 8.0),
child: _buildCategoryItem(
categoriesIcons[index], categories[index], .9),
);
}),
)
],
),
),
),
),
);
Widget _buildCollapsedInformationWidget() => Row(
children: [
Text("Recent"),
Spacer(),
Container(
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.green[400]),
),
),
Text(
' I ',
style: TextStyle(fontSize: 20, color: Colors.black12),
),
Container(
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.red[400]),
),
)
],
);
Widget _buildCategoryItem(
IconData data, String categoryTitle, double percentage) =>
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.black12),
borderRadius: BorderRadius.circular(28),
color: Colors.blue[400]),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(
data,
size: 28,
color: Colors.white,
),
),
),
Container(
width: 40,
height: 40,
child: CircularProgressIndicator(
value: percentage,
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.white),
),
)
],
),
Container(
width: 72,
alignment: Alignment.center,
child: Text(categoryTitle,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
maxLines: 1,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.black45)),
)
],
);
...
}
When it's possible..Use dependend on parent size widgets insted of calcualting children sizes manualy.
FittedBox. Can scale the font size of the children widget according on parents size and fit parameter.
ConstrainedBox, BoxConstraints.tightFor
Expanded. Probably you know how it works.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
floating: false,
delegate: DashboardHeaderPersistentDelegate(),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, i) => Card(
margin: const EdgeInsets.all(10),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
flex: 1,
child: Text(
i.toString(),
),
),
const Expanded(
flex: 3,
child: Text('Text'),
),
],
),
),
),
childCount: 100,
),
),
],
);
}
}
const categories = [
'Grocieries',
'Transport',
'House Rent',
'Shopping',
'Career'
];
const categoriesIcons = [
Icons.ac_unit,
Icons.access_alarms,
Icons.dashboard,
Icons.accessible_forward,
Icons.backspace,
];
class DashboardHeaderPersistentDelegate extends SliverPersistentHeaderDelegate {
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
double shrinkPercentage = min(1, shrinkOffset / (maxExtent - minExtent));
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent,
),
),
child: Material(
elevation: 0,
shadowColor: Colors.white,
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ConstrainedBox(
constraints: BoxConstraints.tightFor(
height: max(
60,
100 * (1 - shrinkPercentage),
),
),
child: FittedBox(
child: Container(
padding: EdgeInsets.all(20),
width: 200,
child: const Text(
'\$ 5329.05',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 30,
fontWeight: FontWeight.w500,
),
),
),
),
),
Expanded(
child: Stack(
alignment: Alignment.bottomCenter,
children: [
if (shrinkPercentage != 1)
Opacity(
opacity: 1 - shrinkPercentage,
child: _buildInformationWidget(context),
),
if (shrinkPercentage != 0)
Opacity(
opacity: shrinkPercentage,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: _buildCollapsedInformationWidget(),
),
),
],
),
)
],
),
),
),
);
}
Widget _buildInformationWidget(BuildContext context) => ClipRect(
child: OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
child: FittedBox(
fit: BoxFit.fitWidth,
alignment: Alignment.center,
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text(
'AVAILABLE BALANCE',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.green[400],
),
),
),
const Text(
' I ',
style: TextStyle(
fontSize: 20,
color: Colors.black12,
),
),
Container(
width: 100,
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 18,
fontWeight: FontWeight.w700,
color: Colors.red[400],
),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 12, top: 12),
alignment: Alignment.centerLeft,
child: const Text(
"CATEGORIES",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w900,
color: Colors.black26,
),
),
),
Container(
height: 88,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(
left: (index == 0) ? 24.0 : 8.0,
right: (index == categories.length - 1)
? 24.0
: 8.0),
child: _buildCategoryItem(
categoriesIcons[index],
categories[index],
.9,
),
);
},
),
)
],
),
),
),
),
);
Widget _buildCollapsedInformationWidget() => Row(
children: [
const Text("Recent"),
const Spacer(),
Container(
child: Text(
'\$ 11200',
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.green[400],
),
),
),
const Text(
' I ',
style: TextStyle(
fontSize: 20,
color: Colors.black12,
),
),
Container(
child: Text(
'\$ 400',
style: TextStyle(
fontFamily: 'Barlow',
fontSize: 14,
fontWeight: FontWeight.w700,
color: Colors.red[400],
),
),
)
],
);
Widget _buildCategoryItem(
IconData data, String categoryTitle, double percentage) =>
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: Colors.black12,
),
borderRadius: BorderRadius.circular(28),
color: Colors.blue[400],
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Icon(
data,
size: 28,
color: Colors.white,
),
),
),
Container(
width: 40,
height: 40,
child: CircularProgressIndicator(
value: percentage,
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.white),
),
)
],
),
Container(
width: 72,
alignment: Alignment.center,
child: Text(
categoryTitle,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
maxLines: 1,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Colors.black45,
),
),
)
],
);
#override
double get maxExtent => 300;
#override
double get minExtent => 80;
#override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}

Flutter: Updating UI from outside of a StatefulWidget

I am new to flutter, and working on a shopping cart project. i don't know how exatly i am suppose to ask this question but, here is what i wanted.
I am trying to update my UI when the cart item and prices changes, which means to display sum amount of products from ListView (Stateful widget) to main OrderPage Stateful widget. I know about setState() method, but i think i should use some callback methods here, dont know exactly.
I have explained in short in Image - see below img
What i have done: when user modify cart products, I have saved the value (price/product/count) in to constant value , i calculate the value and save in constant value, and later use that const var in Main widget (Main Ui), which does update when i close and reopen the page, but could not able to update when button pressed (product +/-buttons)
What i want to do is,
Update my total value when +/- buttons are pressed.
Here is my full code:
class cartConstant{
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text("Your order Summery",style: TextStyle(color: Colors.black54),),
centerTitle: true,
),
body: Container(
child:
FutureBuilder(
builder: (context, snapshot){
// var datas = snapshot.data;
return
ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index){
// Cart cart = datas[index];
return CartListView();
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i,int priceC){
cartConstant.packageCount = i*priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: (){
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap:(){
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {
},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
you can also check from my cart screen shot below:
You can copy paste run full code below
You can use callback refresh() and pass callback to CartListView
code snippet
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
...
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
...
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
...
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
working demo
full code
import 'package:flutter/material.dart';
class cartConstant {
static int packageCount;
static List<int> list;
}
class OrderPage extends StatefulWidget {
#override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
int data = 3;
void refresh() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
automaticallyImplyLeading: true,
iconTheme: IconThemeData(
color: Colors.black54, //change your color here
),
backgroundColor: Colors.white,
elevation: 1,
title: Text(
"Your order Summery",
style: TextStyle(color: Colors.black54),
),
centerTitle: true,
),
body: Container(
child: FutureBuilder(
builder: (context, snapshot) {
// var datas = snapshot.data;
return ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: data,
itemBuilder: (BuildContext context, int index) {
// Cart cart = datas[index];
return CartListView(refresh);
},
padding: EdgeInsets.symmetric(horizontal: 10.0),
scrollDirection: Axis.vertical,
);
},
),
),
bottomNavigationBar: _buildTotalContainer(),
);
}
Widget _buildTotalContainer() {
return Container(
height: 220.0,
padding: EdgeInsets.only(
left: 10.0,
right: 10.0,
),
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Subtotal",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
cartConstant.packageCount.toString(),
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
),
SizedBox(
height: 15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Discount",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"0.0",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 10.0,
),
Divider(
height: 2.0,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Cart Total",
style: TextStyle(
color: Color(0xFF9BA7C6),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
Text(
"8000",
style: TextStyle(
color: Color(0xFF6C6D6D),
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20.0,
),
GestureDetector(
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => SignInPage()));
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(35.0),
),
child: Center(
child: Text(
"Proceed To Checkout",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(
height: 20.0,
),
],
),
);
}
}
class CartListView extends StatefulWidget {
VoidCallback callback;
CartListView(this.callback);
#override
_CartListViewState createState() => _CartListViewState();
}
class _CartListViewState extends State<CartListView> {
int _counter = 1;
int getPrice(int i, int priceC) {
cartConstant.packageCount = i * priceC;
return cartConstant.packageCount;
}
#override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFD3D3D3), width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
setState(() {
_counter++;
if (_counter > 20) {
_counter = 20;
}
});
widget.callback();
},
child: Icon(Icons.add, color: Color(0xFFD3D3D3))),
Text(
"$_counter",
style: TextStyle(fontSize: 18.0, color: Colors.grey),
),
InkWell(
onTap: () {
setState(() {
_counter--;
if (_counter < 2) {
_counter = 1;
}
});
widget.callback();
},
child: Icon(Icons.remove, color: Color(0xFFD3D3D3))),
],
),
),
),
SizedBox(
width: 20.0,
),
Container(
height: 70.0,
width: 70.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/food.jpg"),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(35.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
blurRadius: 5.0,
offset: Offset(0.0, 2.0))
]),
),
SizedBox(
width: 20.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Employee Package",
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
Container(
height: 25.0,
width: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Row(
children: <Widget>[
Text("Price",
style: TextStyle(
color: Color(0xFFD3D3D3),
fontWeight: FontWeight.bold)),
SizedBox(
width: 5.0,
),
InkWell(
onTap: () {},
child: Text(
getPrice(_counter, 2000).toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
),
SizedBox(
width: 10.0,
),
],
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {},
child: Icon(
Icons.cancel,
color: Colors.grey,
),
),
],
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: OrderPage(),
);
}
}
When the button is tapped, you just need to update the Subtotal amount and cart total.
Step 1 : Replace the harcoded value by a variable. So, something like :
Row(
children: <Widget>[
Text(
"Subtotal",
style: ...
),
Text(
"$subTotal",
style: ....
),
],
),
Step 2 : Now, add a code to calcualte subTotal and cartTotal. You already have code which increments and decrements the variable _counter. You just need to tweak that part like :
setState( (){
_counter++;
// So, the quantity is increased. Just get the price of current item and add in the sub total.
subTotal += priceC;
cartTotal = subTotal - discount;
} );