I want to show orders list with all details in each list item including amount, cart items and timer. Each list view item is a StatefulWidget. The issue I am facing right now is that when new a order is placed it displays in listview but initState() for newly added item is not called and because of that issue my timer also not starts.
This is my code for list view items.
class CardWidget extends StatefulWidget {
String tabText;
Order order;
int index;
List<Map<String, dynamic>> orderStatus;
Function(Order) removeOrder;
Function(Order) updateOrder;
int listIndex;
Function(String) rejectOrder;
CardWidget({
this.tabText,
this.order,
this.index,
this.orderStatus,
this.removeOrder,
this.updateOrder,
this.listIndex,
this.rejectOrder,
});
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return CardWidgetState();
}
}
class CardWidgetState extends State<CardWidget> {
Duration countdownDuration;
TextEditingController min = new TextEditingController();
Duration duration = Duration();
Timer timer;
Color textColor;
String minutes = '00';
String seconds = '00';
bool docPrinted = false;
bool noPrinterFound = false;
Color sectionColors;
String rejectionMsg = '';
bool statusUpdated = true;
bool orderCompleted = false;
@override
void dispose() {
super.dispose();
min.dispose();
if (timer != null) timer.cancel();
}
@override
void initState() {
super.initState();
if (widget.order.currentStatusID == widget.order.nextStatusId) {
orderCompleted = true;
} else if (widget.order.orderFrom == 'mobile_app' ||
widget.order.orderFrom == 'web') {
if (widget.order.currentStatusTxt.toLowerCase() == 'placed') {
DateTime currentTime = DateTime.now().subtract(Duration(hours: 5));
DateTime orderTime = DateFormat("yyyy-MM-ddTHH:mm:ss")
.parse(widget.order.dateTime)
.add(Duration(minutes: 5));
print(
'ORDER CARD ${widget.order.id} ${currentTime.difference(orderTime).inSeconds}');
int minDiff = -currentTime.difference(orderTime).inSeconds;
if (minDiff <= 300 && !minDiff.isNegative) {
countdownDuration = Duration(seconds: minDiff);
duration = countdownDuration;
startTimer();
}
} else {
if (timer != null) timer.cancel();
}
}
}
void startTimer() {
timer = Timer.periodic(Duration(seconds: 1), (_) => addTime());
}
void addTime() {
final sec = duration.inSeconds - 1;
if (sec == 0) {
timer?.cancel();
rejectOrder();
} else {
duration = Duration(seconds: sec);
String twoDigits(int n) => n.toString().padLeft(2, '0');
setState(() {
minutes = twoDigits(duration.inMinutes.remainder(60));
seconds = twoDigits(duration.inSeconds.remainder(60));
});
}
}
}
This is my code for listview.
updateOrderList(List<Order> newList)
{
setState(() {
newordersList=List.from(newList);
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
child: newordersList.length != 0
? Stack(
fit: StackFit.expand,
children: [
Positioned(
right: 12.7,
top: 0,
bottom: 0,
child: Container(
width: 10,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.grey[300], width: 2),
),
),
),
Positioned(
right: 7.5,
top: 5,
bottom: 5,
left: 0,
child: DraggableScrollbar.arrows(
controller: scrollController,
alwaysVisibleScrollThumb: true,
backgroundColor: Theme.of(context).focusColor,
heightScrollThumb: 150,
child: StaggeredGridView.countBuilder(
crossAxisCount: 3,
padding: EdgeInsets.only(
left: 20, top: 15, bottom: 15, right: 30),
itemCount: newordersList.length,
controller: scrollController,
itemBuilder: (BuildContext context, int index) =>
CardWidget(
tabText: 'new_orders',
order: newordersList[index],
index: widget.tabIndex,
removeOrder: (order) {
setState(() {
newordersList.remove(order);
});
},
updateOrder: (order) {
updateOrder(order, index);
},
listIndex: index,
rejectOrder: (orderID) {
rejectOrder(orderID);
},
),
staggeredTileBuilder: (int index) =>
new StaggeredTile.fit(1),
mainAxisSpacing: 15.0,
crossAxisSpacing: 15.0,
),
),
),
],
)
: Center(
child: Text(
'No Record found',
style: GoogleFonts.roboto(
textStyle: Theme.of(context).textTheme.subhead.merge(
TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
),
),
),
);
}
And this is my code in which I am adding new item to list.I am using GlobalKey() for list view and calling the function:
orderListKey.currentState.updateOrderList(mobileOrders)
of listview widget to update list.
updateForNewOrder(Order order) {
if (order.orderFrom == 'mobile_app' || order.orderFrom == 'web') {
mobileOrders.add(order);
mobileOrders.sort((a, b) => b.id.compareTo(a.id));
setState(() {
mobileOrderCount = mobileOrders.length;
tabs[2]['count'] = mobileOrderCount;
if (currentTab != 2) {
tabs[2]['animate'] = true;
globals.animatedTabs[2] = true;
}
});
globals.mobileOrders = mobileOrders;
orderListKey.currentState.updateOrderList(mobileOrders);
}
}
Widget orderView() {
return Container(
child: TabBarView(
controller: _tabController,
children: <Widget>[
KioskTabView(
key: orderListKey,
neworders: mobileOrders,
completedorders: [],
tabIndex: 2,
rejectOrder: (orderid) {
rejectOrder(orderid);
},
), ////////////MOBILE ORDERS
],
),
);
}
Anyone please help me out to solve this issue. Thanks