I´m using flutter with a calendar carousel (https://pub.dev/packages/flutter_calendar_carousel)
For each day for which there is an entry in the database, I want to display an icon in the calendar. What is the best way to do this?
That´s my current code:
Please check the part with the customDayBuilder
class _CalendarScreenState extends State<CalendarScreen> {
DateTime _currentDate;
openNewEntryDialog(BuildContext context, date) {
setState(() {
_currentDate = date;
});
showBarModalBottomSheet(
context: context,
builder: (BuildContext context, scrollController) {
return AddCalendarEntry(
scrollController: scrollController,
currentDate: _currentDate,
);
});
}
#override
Widget build(BuildContext context) {
final calendarEntriesData = Provider.of<CalendarEntries>(context);
void initState() {
_currentDate = widget._currentDate;
super.initState();
}
dayPressed(date, events) {
this.setState(() => _currentDate = date);
}
return Material(
child: CupertinoPageScaffold(
backgroundColor: Colors.white,
navigationBar: CupertinoNavigationBar(
trailing: IconButton(
icon: Icon(Icons.add),
color: Colors.white,
onPressed: () => openNewEntryDialog(context, DateTime.now())),
middle: Text("Juni 2020",
style: Theme.of(context).appBarTheme.textTheme.headline1),
backgroundColor: Theme.of(context).primaryColor,
),
child: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: Column(
children: <Widget>[
Expanded(
child: CalendarCarousel(
markedDateIconBorderColor: Theme.of(context).primaryColor,
weekdayTextStyle:
TextStyle(color: Theme.of(context).primaryColor),
daysTextStyle:
TextStyle(color: Theme.of(context).primaryColor),
todayButtonColor: Theme.of(context).primaryColor,
weekendTextStyle: TextStyle(color: Colors.black),
locale: "de",
selectedDayButtonColor: Colors.grey.shade100,
selectedDateTime: _currentDate,
headerTextStyle: TextStyle(
color: Theme.of(context).primaryColor, fontSize: 25),
onDayPressed: (DateTime date, List<Event> events) =>
dayPressed(date, events),
onDayLongPressed: (DateTime date) =>
openNewEntryDialog(context, date),
customDayBuilder: (bool isSelectable,
int index,
bool isSelectedDay,
bool isToday,
bool isPrevMonthDay,
TextStyle textStyle,
bool isNextMonthDay,
bool isThisMonthDay,
DateTime day) {
return FutureBuilder(
future: calendarEntriesData.getAll(),
builder: (BuildContext context,
AsyncSnapshot<List<CalendarEntry>> snapshot) {
if (!snapshot.hasData ||
snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
for (final entry in snapshot.data) {
var temp =
DateTime.parse(entry.dateTime).toUtc();
var d1 = DateTime.utc(
temp.year, temp.month, temp.day);
var d2 = DateTime.utc(
day.year, day.month, day.day);
if (d2.compareTo(d1) == 0) {
return Center(
child: Icon(Icons.local_airport));
}
}
}
});
},
),
),
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(top: 35),
child: FutureBuilder<List<CalendarEntry>>(
future: calendarEntriesData
.getCurrentMonthEntries(_currentDate != null
? _currentDate
: DateTime.now()),
builder: (BuildContext context,
AsyncSnapshot<List<CalendarEntry>> snapshot) {
if (!snapshot.hasData ||
snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Container(
height: 100,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context,
int index) {
return ListTile(
title: Text(snapshot
.data[index].servicePartner
.toString()),
subtitle: snapshot.data[index]
.dateTime ==
null
? Text("Unbekannt")
: Text(DateFormat(
"dd.MM.yyyy")
.format(DateTime.parse(
snapshot.data[index]
.dateTime))),
trailing: Text((snapshot
.data[index]
.minutes /
60)
.toString() +
" Stunden"),
);
}));
}
})))
],
),
)));
}
}
How you can see, I´m using a FutureBuilder to check all database entries. And if a day matches, I show an Icon on this day. This works in general, but
I have some errors on the screen
The performance is very bad, because there is some flickering..for each click on another day the widget renders completely. I don´t want this.
How could I improve my code? How could I do this better?
Thanks so much for your help!
Please use the button and button style for this to generate a clickable.
Also resolved your issue.
Widget renderDay(
bool isSelectable,
int index,
bool isSelectedDay,
//bool isToday,
bool isPrevMonthDay,
TextStyle? textStyle,
TextStyle defaultTextStyle,
bool isNextMonthDay,
bool isThisMonthDay,
DateTime now,
) {
final EventList<T>? markedDatesMap = widget.markedDatesMap;
List<Event> markedEvents =
widget.markedDatesMap!.getEvents(now) as List<Event>? ?? [];
return Container(
child: ElevatedButtonTheme(
data: ElevatedButtonThemeData(
style: ButtonStyle(
side: MaterialStateProperty.resolveWith<BorderSide>((states) =>
BorderSide(
color: ColorConstants.WHITE)),
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(states) => markedEvents.length > 0 &&
!isPrevMonthDay &&
!isNextMonthDay
? _getStatusColor(
markedEvents[0].dayStatus!.toLowerCase())
: isSelectedDay && widget.selectedDayButtonColor != null
? widget.selectedDayButtonColor
: widget.dayButtonColor,
),
shape: MaterialStateProperty.resolveWith<OutlinedBorder>((_) {
return RoundedRectangleBorder(
borderRadius: BorderRadius.circular(80));
}),
textStyle: MaterialStateProperty.resolveWith<TextStyle>(
(states) =>
TextStyle(color: ColorConstants.BUTTON_BG_COLOR)),
padding: MaterialStateProperty.all(
EdgeInsets.all(widget.dayPadding),
),
),
),
child: ElevatedButton(
onPressed:
widget.disableDayPressed ? null : () => _onDayPressed(now),
child: Stack(
children: <Widget>[
getDayContainer(
isSelectable,
index,
isSelectedDay,
// isToday,
isPrevMonthDay,
textStyle,
defaultTextStyle,
isNextMonthDay,
isThisMonthDay,
now),
],
),
),
),
);
}
Related
I am trying to use the SwitchTileList to show all my categories and toggle them on/off however it seems to either not change state/toggle or it will toggle all of them together.
At the moment the code below the showdefault items are on as should be and the rest are off, however it will not toggle any of them at the moment.
return FutureBuilder(
future: amenityCategories,
builder:
(BuildContext context, AsyncSnapshot<AmenityCategories> snapshot) {
if (snapshot.hasData) {
return ListView(
padding: EdgeInsets.zero,
children: [
SizedBox(
height: 85.0,
child: DrawerHeader(
child: Text(
'Show/Hide Map Pins',
style: new TextStyle(fontSize: 18.0, color: Colors.white),
),
decoration: const BoxDecoration(
color: Colors.green,
),
),
),
SizedBox(
height: double.maxFinite,
child: ListView.builder(
itemCount: snapshot.data!.categories.length,
itemBuilder: (context, index) {
bool toggle = false;
if (snapshot.data!.categories[index].showbydefault == 1) {
toggle = true;
}
return SwitchListTile(
title: Text(
snapshot.data!.categories[index].categoryname),
value: toggle,
onChanged: (bool val) {
if (val != toggle) {
setState(() {
toggle = !toggle;
});
}
});
},
),
),
],
);
}
return Container();
});
}
You must use a separate variable for each individual ListTile. Give your category an additional variable isActive and work with it.
onChanged: (bool val) {
if (val != snapshot.data!.categories[index].isActive) {
setState(() {
snapshot.data!.categories[index].isActive = !snapshot.data!.categories[index].isActive;
});
}
I am 9 displaying values of each employee from table.
Tried with Listview with row with containers, onSelect is taking more space and not looking good.
ListTiles but not able to fit all values.
Could you suggest best practices?
body: SafeArea(
child: Container(
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: contacts.length,
itemBuilder: (BuildContext context, int index) {
// return item
return ContactItem(
contacts[index].name,
contacts[index].phoneNumber,
contacts[index].isSelected,
index,
Widget ContactItem(
String name, String phoneNumber, bool isSelected, int index) {
return ListTile(
title: Text(
name,
style: TextStyle(
fontWeight: FontWeight.w500,
),
),
//subtitle: Text(phoneNumber),
subtitle: Text('$phoneNumber' '\n' '$phoneNumber'),
isThreeLine: true,
leading: isSelected
? Icon(
Icons.check_circle,
color: Colors.green[700],
)
: Icon(
Icons.check_circle_outline,
color: Colors.grey,
),
onTap: () {
setState(() {
contacts[index].isSelected = !contacts[index].isSelected;
if (contacts[index].isSelected == true) {
selectedContacts.add(ContactModel(name, phoneNumber, true));
} else if (contacts[index].isSelected == false) {
selectedContacts.removeWhere(
(element) => element.name == contacts[index].name);
}
});
},
));
I am trying to update an array in flutter. I found out that it is not possible directly.
I have understood that I must first create a list[], transfer my document fields value into the created list, then I must update the information in my list and only then can I can update my Firebase Firestore array with my updated list.
My code is below. Problem is, when I use my function the simulator crashes and I am getting the error lost connection.
I am looking for any advice. Many thanks.
List listTest =[];
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
class DetailScreen_CheckList_V3 extends StatefulWidget {
//final Map listName;
final docID;
const DetailScreen_CheckList_V3( this.docID,{
Key key}) : super(key: key);
#override
_DetailScreen_CheckList_V3State createState() => _DetailScreen_CheckList_V3State(docID);
}
class _DetailScreen_CheckList_V3State extends State<DetailScreen_CheckList_V3> {
// Map listName;
var docID;
_DetailScreen_CheckList_V3State( //this.listName,
this.docID);
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Your list items'),
leading:
InkWell(
child:
Icon(Icons.fast_rewind_outlined),
onTap: () {
Navigator.pop(context);
},),
),
body: MyBody(context, docID),
floatingActionButton: FloatingActionButton(
onPressed: () {
showAddNewItemToAList();
setState(() {});
},
child: const Icon(Icons.add),
backgroundColor: Colors.blue,
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
);
}
Widget MyBody(BuildContext context, var docID) {
return SingleChildScrollView(
child: Column(
children: [
Container(
height: MediaQuery
.of(context)
.size
.height / 1.4,
width: MediaQuery
.of(context)
.size
.width,
child: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('lists')
.doc(docID)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
DocumentSnapshot data = snapshot.requireData;
return ListView.builder(
itemCount: data['allItems'].length,
itemBuilder: (context, index) {
return Card(
child:
InkWell(
child: ListTile(
leading: data['allItems'][index]['itemChecked'] ==
'Yes' ? Icon(
Icons.check_box,
color: Colors.blue,) : Icon(
Icons.check_box_outline_blank),
title:
Text(
(data['allItems'][index]['itemName'])),
onTap: () {
String checked = data['allItems'][index]['itemChecked'];
String myItemName = data['allItems'][index]['itemName'];
String myListName = data['listName'];
listTest.addAll(data['allItems']);
print('before');
print (listTest);
setState(() {
if (checked == 'Yes') {
checked = 'No';
listTest[index]['itemChecked'] = checked;
print('after');
print(listTest);
myTest(myListName,index);
}
else {
checked = 'Yes';
listTest[index]['itemChecked'] = checked;
print('after');
print(listTest);
myTest(myListName,index);
}
});
}
),
onTap: () {
},)
);
});
}
}))
]),
);
}
void showAddNewItemToAList() {
TextEditingController _noteField = new TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return CustomAlertDialog(
content: Container(
width: MediaQuery
.of(context)
.size
.width / 1.3,
height: MediaQuery
.of(context)
.size
.height / 4,
child: Column(
children: [
TextField(
controller: _noteField,
maxLines: 4,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1.0),
),
),
),
SizedBox(height: 10),
Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(25.0),
color: Colors.white,
child: MaterialButton(
minWidth: MediaQuery
.of(context)
.size
.width / 1.5,
onPressed: () {
if (_noteField.text != '') {
setState(() {
AddObjectItemToArray(_noteField.text);
});
Navigator.of(context).pop();
}
else {
return;
}
},
padding: EdgeInsets.fromLTRB(10.0, 15.0, 10.0, 15.0),
child: Text(
'Add Item',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
)
],
),
),
);
});
}
Future AddObjectItemToArray(newItemName,) async {
AllItems _allItems = AllItems(newItemName, 'No');
FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('lists')
.doc(docID).update({
"allItems": FieldValue.arrayUnion([_allItems.toMap()])
},);
}
Future ModifyCheckedStatus(newItemName, newCheckedStatus,
currentListName) async {
AllItems _allItems = AllItems(newItemName, newCheckedStatus);
FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('lists')
.doc(docID).update(
{'listName': currentListName,
"allItems": ([_allItems.toMap()]),
}, //SetOptions(merge: true),
);
}
Future myTest(currentListName,index) async {
FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('lists')
.doc(docID).set(
{'listName': currentListName,
"allItems": [listTest],
},//SetOptions(merge: true)
);
}
}
So I guess your AddObjectToArray method is working well, you are correctly using arrayUnion. But then the ModifyCheckStatus is not working as expected because you are still using arrayUnion.
ArrayUnion adds an object to the array. What you have to do in ModifyCheckStatus is to extract all items, toggle the checked status of a particular item, then update the entire items list in Firebase (instead of using arrayUnion). This should only be in ModifyCheckStatus.
Something like the following
Future ModifyCheckedStatus(newItemName, newCheckedStatus,
currentListName) async {
// TODO: obtain all items
// changed the checked status of a particular item
allItems.where((i) => i.name == item.name).forEach((i) {
i.checked = !i.checked;
});
// update as you did
FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('lists')
.doc(docID)
.update({"allItems": allItems});
}
I want to retrieve the new created document id and display the document data in a new page. How can i get the document id? When onPressed() the elevated button, I want to retrieve the document data based on its id.
How can I bring the document id from addDiagnose(_type, _symptomsResult) so that I can navigate it to another page.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DiagnosisPage(documentId: documentId),
)
);
This is my current code.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:multiselect_formfield/multiselect_formfield.dart';
import 'package:petbuddies/user/diagnosis/diagnose_history.dart';
import 'package:petbuddies/user/diagnosis/diagnosis.dart';
class CheckerPage extends StatefulWidget {
const CheckerPage({Key? key}) : super(key: key);
#override
_CheckerPageState createState() => _CheckerPageState();
}
class _CheckerPageState extends State<CheckerPage> {
//retrieve options
final _formKey = GlobalKey<FormState>();
void _petTypeDropDownItemSelected(String newValueSelected) {
setState(() {
petType = newValueSelected;
});
}
clearText(){
_symptoms?.clear();
}
#override
void initState(){
super.initState();
_symptoms = [];
_symptomsResult = [];
}
List? _symptoms;
late List<dynamic> _symptomsResult;
var petType;
var _type;
final Stream<QuerySnapshot> petTypeStream = FirebaseFirestore.instance.collection('pet type').orderBy('name').snapshots();
final Stream<QuerySnapshot> symptomsStream = FirebaseFirestore.instance.collection('symptoms').orderBy('name').snapshots();
DocumentReference diagnosis = FirebaseFirestore.instance.collection('diagnosis').doc();
//store the diagnosis result
User? user = FirebaseAuth.instance.currentUser;
Future<void> addDiagnose(_type, _symptomsResult) async {
String petChosen = this._type;
List symptomsChosen = this._symptomsResult.toList();
QuerySnapshot<Map<String, dynamic>> snapshot =
await FirebaseFirestore.instance.collection("disease")
.where('petType',isEqualTo: petChosen)
.where('symptoms',arrayContainsAny: symptomsChosen)
.get();
List<String> diseaseRef = snapshot.docs.map((e) => e.id).toList();
String createdby = user!.uid;
Timestamp date = Timestamp.now();
List possibleDisease = diseaseRef.toList();
final data = {
'created by': createdby,
'date': date,
'pet chosen': petChosen,
'symptoms chosen': symptomsChosen,
'possible disease': possibleDisease,
};
//set document data
return diagnosis
.set(data)
.then((value) => print('Diagnose Report Added'))
.catchError((error)=>print("Failed to add: $error")
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue[900],
title: const Text("Pet Symptoms Checker",
style: TextStyle(color: Colors.white),
),
),
body: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
child: ListView(
children: [
Align(
alignment: Alignment.bottomRight,
child: TextButton(
child: const Text(
'History',
style: TextStyle(fontSize: 18),
),
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => const DiagnoseHistoryPage(),));
},
),
),
Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
border: Border.all(width: 3, color: Colors.indigo,),
borderRadius: const BorderRadius.all(Radius.circular(30)),
),
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: petTypeStream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Container(
padding: const EdgeInsets.only(bottom: 16.0),
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.fromLTRB(12.0, 10.0, 10.0, 10.0),
child: const Text(
"Pet Type",
style: TextStyle(fontSize: 20),
),
),
),
Expanded(
flex: 3,
child: Row(
children: [
const SizedBox(width: 30,),
DropdownButton(
value: petType,
onChanged: (valueSelectedByUser) {
_petTypeDropDownItemSelected(valueSelectedByUser.toString());
},
hint: const Text('Choose Pet Type',),
underline: Container(),
items: snapshot.data!.docs.map((DocumentSnapshot document) {
return DropdownMenuItem<String>(
value: document.get('name'),
child: Text(document.get('name')),
);
}).toList(),
),
],
),
),
],
),
);
}),
StreamBuilder(
stream: symptomsStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if(snapshot.hasError){
print('Something went wrong');
}
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
child: CircularProgressIndicator(),
);
}
final List symptomsList = [];
snapshot.data!.docs.map((DocumentSnapshot document){
Map a = document.data() as Map<String, dynamic>;
symptomsList.add(a['name']);
a['id'] = document.id;
}).toList();
return MultiSelectFormField(
autovalidate: AutovalidateMode.disabled,
chipBackGroundColor: Colors.blue[900],
chipLabelStyle: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
dialogTextStyle: const TextStyle(fontWeight: FontWeight.bold),
checkBoxActiveColor: Colors.blue[900],
checkBoxCheckColor: Colors.white,
dialogShapeBorder: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0))),
title: const Text(
"Symptoms",
style: TextStyle(fontSize:20),
),
validator: (value) {
if (value == null || value.length == 0) {
return 'Please select one or more symptoms';
}
return null;
},
dataSource: [
for (String i in symptomsList) {'value' : i}
],
textField: 'value',
valueField: 'value',
okButtonLabel: 'OK',
cancelButtonLabel: 'CANCEL',
hintWidget: const Text('Please choose one or more symptoms'),
initialValue: _symptoms,
onSaved: (value) {
if (value == null) return;
setState(() {
_symptoms = value;
}
);
},
);
}
),
const SizedBox(height:50,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () async{
if(_formKey.currentState!.validate()){
setState(() {
_type = petType.toString();
_symptomsResult = _symptoms!.toList();
addDiagnose(_type,_symptomsResult);
final documentId = diagnosis.id;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DiagnosisPage(documentId: documentId),
)
);
clearText();
}
);
}
},
child: const Text(
'Diagnose',
style: TextStyle(fontSize: 18),
),
style: ElevatedButton.styleFrom(primary: Colors.blue[900]),
),
],
),
],
),
)
],
),
),
),
);
}
}
My listview total price code is runing more than once which is adding to the price variable again which is not the correct value ,how to prevent it from runing twice . As per my research my future builder is in build method ,if this is the problem then how to do it ,or any other suggestion would be great.
import 'package:flutter/material.dart';
import 'package:restaurant_ui_kit/models/user.dart';
import 'package:restaurant_ui_kit/screens/checkout.dart';
import 'package:restaurant_ui_kit/util/database_helper.dart';
class CartScreen extends StatefulWidget {
#override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen>
with AutomaticKeepAliveClientMixin<CartScreen> {
var db = new DatabaseHelper();
static int subTotal = 0;
List _users = [];
#override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
body: Padding(
padding: EdgeInsets.fromLTRB(10.0, 0, 10.0, 0),
child: FutureBuilder<List>(
future: db.getAllUsers(),
initialData: List(),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, position) {
final item = snapshot.data[position];
for (int i = 0; i < snapshot.data.length; i++) {
subTotal = subTotal +
int.parse(
User.fromMap(snapshot.data[position]).price);
}
print('toatl is $subTotal');
// get your item data here ...
return Dismissible(
key: UniqueKey(),
child: new Card(
color: Colors.white,
elevation: 2.0,
child: new ListTile(
leading: new CircleAvatar(
child: Text(
"${User.fromMap(snapshot.data[position]).name.substring(0, 1)}"),
),
title: new Text(
"User: ${User.fromMap(snapshot.data[position]).price}"),
subtitle: new Text(
"Id: ${User.fromMap(snapshot.data[position]).id}"),
onTap: () => debugPrint(
"${User.fromMap(snapshot.data[position]).id}"),
),
),
background: slideLeftBackground(),
confirmDismiss: (direction) async {
if (direction == DismissDirection.endToStart) {
final bool res = await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: Text(
"Are you sure you want to delete ${User.fromMap(snapshot.data[position]).name}?"),
actions: <Widget>[
FlatButton(
child: Text(
"Cancel",
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text(
"Delete",
style: TextStyle(color: Colors.red),
),
onPressed: () {
// TODO: Delete the item from DB etc..
setState(() {
// total();
// print(position);
if (position == 0) {
//print('index 0 dai');
db.deleteUser(User.fromMap(
snapshot.data[position])
.id);
//snapshot.data.removeAt(position);
} else {
snapshot.data
.removeAt(--position);
db.deleteUser(User.fromMap(
snapshot.data[position])
.id);
}
//print("removed");
// print('mSubTotal $mSubTotal');
});
Navigator.of(context).pop();
},
),
],
);
});
return res;
}
},
);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
),
floatingActionButton: FloatingActionButton(
tooltip: "Checkout",
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return Checkout();
},
),
);
},
child: Icon(
Icons.arrow_forward,
),
heroTag: Object(),
),
);
}
#override
bool get wantKeepAlive => true;
}
Widget slideLeftBackground() {
return Container(
color: Colors.red,
child: Align(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Icon(
Icons.delete,
color: Colors.white,
),
Text(
" Delete",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
),
textAlign: TextAlign.right,
),
SizedBox(
width: 20,
),
],
),
alignment: Alignment.centerRight,
),
);
}
subTotal is printing like this in terminal the correctvalue is 500 because each item has price of 100 and there are 5 items but as you all know the last value is assigned to the variable
I/flutter ( 3885): Count : 5
I/flutter ( 3885): toatl is 500
I/flutter ( 3885): toatl is 1000
I/flutter ( 3885): toatl is 1500
I/flutter ( 3885): toatl is 2000
I/flutter ( 3885): toatl is 2500
You sum and add values every time build method run. You can reset the subTotal every time or there is a shorter way to sum the values, you can try it; instead of using;
for (int i = 0; i < snapshot.data.length; i++) {
subTotal = subTotal +
int.parse(
User.fromMap(snapshot.data[position]).price);
}
just try this;
subTotal = snapshot.data.fold(0, (previousValue, element) => previousValue + int.tryParse(User.fromMap(item).price));