How to merge new field value to an existing firestore document with flutter? - flutter

I am trying to assign a delivery agent to the order of products with a dropdown containing a list of delivery agents. I am trying to get documentId and merging new field value to the documentId which already exists. But as a result, I a getting a duplicate document with the same documentId containing filed values which I want to merge. kindly help me to understand what I am doing wrong.
full code order_view.dart
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../services/firebase_database.dart';
import '../widgets/snack_bar.dart';
import 'client_address.dart';
import 'dashboard.dart';
import 'package:url_launcher/url_launcher.dart';
class OrderView extends StatefulWidget {
final Map<String, dynamic> orderData;
final List<String> deliveryAgent;
const OrderView(
{Key? key, required this.orderData, required this.deliveryAgent})
: super(key: key);
#override
State<OrderView> createState() => _OrderViewState();
}
class _OrderViewState extends State<OrderView> {
final FirebaseDatabase _database = FirebaseDatabase();
int index = 0;
num totalAmount = 0;
Map<String, dynamic> clientData = {};
getcountTotalAmount() async {
for (var item in widget.orderData["orders"]) {
totalAmount = totalAmount + (item["productPrice"] * item["amount"]);
}
clientData = (await _database.getClientData(widget.orderData["userId"]))!;
setState(() {});
}
#override
void initState() {
getcountTotalAmount();
super.initState();
}
#override
Widget build(BuildContext context) {
bool _isloading = true;
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
elevation: 4,
title: const Text("Open Order"),
actions: [
TextButton(
onPressed: () async {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: const Text(
"Are you sure you want to cancel this order?",
textAlign: TextAlign.center,
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text(
"No",
style:
TextStyle(color: Colors.green, fontSize: 16),
)),
TextButton(
onPressed: () async {
// Navigator.pop(context);
showDialog(
context: context,
builder: (context) {
return LoadingAnimationWidget.inkDrop(
color: Colors.orange,
size: 50,
);
});
await _database.removeOrder(
createTime: widget.orderData["createAt"],
);
Navigator.of(context).pop();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) =>
const AdminDashboard()),
ModalRoute.withName(''),
);
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
message: "Your order is removed",
color: Colors.deepOrange),
);
},
child: const Text(
"Yes",
style: TextStyle(color: Colors.red, fontSize: 16),
)),
],
);
});
},
child: const Text(
"Cancel Order",
style: TextStyle(
color: Colors.red,
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
),
],
),
body: SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: ListView(
physics: const BouncingScrollPhysics(),
children: [
Container(
color: Colors.white,
child: ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 8),
shrinkWrap: true,
itemCount: widget.orderData["orders"].length,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
leading: Image.network(
widget.orderData["orders"][index]["productImage"],
),
title: Text(
widget.orderData["orders"][index]["productTitle"],
),
subtitle: SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Text(
"₹ ${widget.orderData["orders"][index]["productPrice"]}",
style: const TextStyle(
color: Colors.green, fontSize: 12),
),
const Text(" - "),
Text(
widget.orderData["orders"][index]["productUnit"],
style: const TextStyle(fontSize: 12),
),
const Text(" x "),
Text(widget.orderData["orders"][index]["amount"]
.toString()),
const SizedBox(width: 5),
Text(
"Total ₹ ${widget.orderData["orders"][index]["productPrice"] * widget.orderData["orders"][index]["amount"]}",
style: const TextStyle(
color: Colors.green,
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
],
),
),
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider();
},
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Delivery Slot'),
Text(
'${widget.orderData["deliverySlot"]}',
style: const TextStyle(
fontWeight: FontWeight.w500, fontSize: 16),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"Delivery charge: ₹${widget.orderData["taxes"]}",
),
Text(
"Total Price: ₹${totalAmount + widget.orderData["taxes"]}",
style: const TextStyle(
fontWeight: FontWeight.w500, fontSize: 16),
),
],
)
],
),
),
const SizedBox(height: 16),
Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
decoration: const BoxDecoration(
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Ordered on: ${widget.orderData["createAt"]}',
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
Text(
'Delivery at ${widget.orderData["addressType"]}',
),
const SizedBox(
height: 16,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
child: Text(
'Address: ${widget.orderData["address"]}',
),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ClientAddress(
lat: widget.orderData["latitude"],
lag: widget.orderData["longitude"],
)));
},
child: const Text('Open location'))
],
),
],
),
),
const SizedBox(
height: 16,
),
Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Client Details",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 17,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
child: Text(
clientData["username"] ?? "",
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
),
SizedBox(
child: Text(
clientData["contact"] ?? "",
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
),
ElevatedButton.icon(
onPressed: () async {
String telephoneNumber = clientData["contact"];
Uri telephoneUrl = Uri.parse("tel:$telephoneNumber");
if (await canLaunchUrl(telephoneUrl)) {
await launchUrl(telephoneUrl);
}
},
icon: const Icon(
Icons.call,
),
label: const Text('Call'),
)
],
),
],
),
),
const SizedBox(
height: 16,
),
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
padding: const EdgeInsets.only(bottom: 8),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"Delivery Agent",
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
),
),
DropdownButton(
items: widget.deliveryAgent
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e),
),
)
.toList(),
onChanged: (val) {
setState(() {
index =
widget.deliveryAgent.indexOf(val.toString());
});
},
isExpanded: false,
hint: Text(
widget.deliveryAgent[index],
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
),
],
),
ElevatedButton(
onPressed: () async {
bool results;
results = await _database.updateDeliveryAgent(
orderId: widget.orderData["orderId"],
deliveryAgent: widget.deliveryAgent[index].toString(),
);
if (results) {
setState(() {
_isloading = true;
});
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
message: "Delivery agent assigned",
color: Colors.green,
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
message: "Error",
color: Colors.red,
),
);
}
setState(() {
_isloading = true;
});
},
child: const Text('Assign Agent')),
],
)),
],
),
),
);
}
}
firebase_database.dart
CollectionReference<Map<String, dynamic>> testorders =
FirebaseFirestore.instance.collection('testorders');
Future<bool> updateDeliveryAgent(
{required String orderId, required String deliveryAgent}) async {
try {
testorders.doc(orderId).set({
"deliveryAgent": {
"agentName": deliveryAgent,
"agentContact": '',
},
}, SetOptions(merge: true));
return true;
} catch (e) {
if (kDebugMode) {
print("error while assigning delivery agent: $e");
}
}
return false;
}
order.dart
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
padding: const EdgeInsets.only(bottom: 8),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"Delivery Agent",
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
),
),
DropdownButton(
items: widget.deliveryAgent
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e),
),
)
.toList(),
onChanged: (val) {
setState(() {
index =
widget.deliveryAgent.indexOf(val.toString());
});
},
isExpanded: false,
hint: Text(
widget.deliveryAgent[index],
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 15,
),
),
),
],
),
ElevatedButton(
onPressed: () async {
bool results;
results = await _database.updateDeliveryAgent(
orderId: widget.orderData["orderId"],
deliveryAgent: widget.deliveryAgent[index].toString(),
);
if (results) {
setState(() {
_isloading = true;
});
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
message: "Delivery agent assigned",
color: Colors.green,
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
message: "Error",
color: Colors.red,
),
);
}
setState(() {
_isloading = true;
});
},
child: const Text('Assign Agent')),
],
)),

You cannot update a document ID once it's been defined.
See the following answer on alternative steps you can take: https://stackoverflow.com/a/52117929/9063088

There is no way you can have duplicate document IDs inside the same collection. The screenshot shows two documents sharing the same ID but for sure one of them contains one or more white spaces at the end. So there are two situations, the orderId is correct and when you call set() it adds the document with a document ID that doesn't contains white spaces, while in the database there is already one present that contains white spaces, or vice versa. When it comes to document IDs, always call .trim() so it can remove the white spaces from the beginning and from the end.

I fixed this, the main reason was firstly when I created the document with .add() where firebase auto generate the document ID, the and later while merging data in the same document ID it was creating the duplicate document ID maybe with some whitespace in it which was not visible.
But to rectify I created the data with .set() by generating the document by my own and later while merging data uses the same document ID to merge new fields in the same document ID. and finally it worked.

Related

Flutter firebase realtime database getting user details from join request key

I am new to flutter. Seeking help with flutter and firebase real-time database. In the first image of my 'request' child, I want to retrieve all requests to a list and display the user details from the 'users' child using that list.
[request child]
[users child]:
Currently, I am using a streambuilder to get the keys but I want to show the user details under the keys. What is the best way to do that?
[Current streambuilder]
Current code
StreamBuilder<dynamic>(
stream: ref
.child('house')
.child(widget.house)
.child('request')
.child('joinReq')
.orderByChild('id')
.onValue,
builder: (context, snapshot) {
final tilesList = <Card>[];
if (snapshot.hasData) {
final joinReq = Map<String, dynamic>.from(
(snapshot.data!).snapshot.value);
joinReq.forEach((key, value) {
final nextJoinReq = Map<String, dynamic>.from(value);
nextJoinReq['key'] = key;
final joinTile = Card(
margin: const EdgeInsets.symmetric(
vertical: 5, horizontal: 7),
//elevation: 3,
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
nextJoinReq['id'],
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 12,
color: Colors.red,
),
),
GestureDetector(
onTap: (() {
Alert(
context: context,
//closeIcon: const Icon(Icons.close),
//title: 'LOG OUT!',
//desc: 'Do you want to log out?',
//content: const CircularProgressIndicator(),
content: Row(
children: [
const Icon(Icons.clear, size: 40),
const SizedBox(
width: 10,
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Text(
'Delete request!',
style: TextStyle(
fontSize: 20,
color: Colors.red,
),
),
SizedBox(
width: 160,
child: Text(
'Do you want to remove \' ${nextJoinReq['id']}s \' request to join?',
textAlign: TextAlign.start,
style: const TextStyle(
fontSize: 15,
color: Colors.black,
),
),
),
],
),
],
),
style: const AlertStyle(
backgroundColor: Colors.white,
isCloseButton: false,
// isOverlayTapDismiss: false,
),
buttons: [
DialogButton(
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
child: const Text(
'No',
style: TextStyle(color: Colors.white),
),
),
DialogButton(
color: Colors.black,
onPressed: () {
Navigator.pop(context);
ref
.child('house')
.child(widget.house)
.child('request')
.child('joinReq')
.child(nextJoinReq['key'])
.remove()
.whenComplete(() => {
showSnackBar(context,
'Request deleted')
});
},
child: const Text(
'Yes',
style: TextStyle(color: Colors.white),
),
),
],
).show();
}),
child: const Icon(
Icons.clear,
size: 25.0,
color: Colors.black,
),
),
],
),
),
);
tilesList.add(joinTile);
});
}
return ListView(
children: tilesList,
);
},
)

How to extract specific value from object stored in cloud firestore and get the sum of those values according to needed filters?

I am having an issue in extracting specific value and querying with it. Please guide me on this.
Here is a data structure : (Using flutter/dart and cloudFirestore 3.1.18)
What I want to do is
extract the value of "amount" acccording to "isIncome" (boolean) from all the documents in "entries" collection and get the sum of those extracted amount.
to get the all the "amount" done in a day according to "entryLog" as well and show filtered data (according to date and income type) in listview builder as well.
This is the code I have return for getting all those entries in a stream
Stream<List<Entries>> streamAllEntries() {
var uid = FirebaseAuth.instance.currentUser.uid;
var stream = _db
.collection('entries')
.where("addedBy", isEqualTo: uid)
.orderBy('entryLog', descending: true)
.snapshots()
.map((event) =>
event.docs.map((e) => Entries.fromJson(e.data())).toList());
log(stream.toString());
return stream;
}
and this is my code for Showing DailyReports (here -- entries)
class DailyReports extends StatefulWidget {
const DailyReports({Key? key}) : super(key: key);
#override
State<DailyReports> createState() => _DailyReportsState();
}
class _DailyReportsState extends State<DailyReports> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: getBody(),
);
}
Widget getBody() {
var entries = Provider.of<List<Entries>>(context);
var size = MediaQuery.of(context).size;
return Container(
margin: const EdgeInsets.only(bottom: 5),
child: Column(
children: [
//header card
SizedBox(
height: 140,
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 10, bottom: 10, right: 10, left: 10),
child:
//header row
Column(
children: [
//title
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"Transactions",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 22),
),
Icon(Ionicons.search, color: ColorTheme().blackColor),
],
),
//day tabs
const SizedBox(height: 10),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: days.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
var day = days[index];
return weekTabs(size, index, day);
},
),
),
),
],
),
),
),
),
//income/expense card
incomeExpenseStatus(entries),
testbtn(),
// transaction summary
Expanded(child: transactionSection(entries)),
],
),
);
}
testbtn() {
return IconButton(
onPressed: () async {
await FirestoreService().addToAmountCollection(1000, true, "entry8");
},
icon: const Icon(Icons.mail, color: Colors.white));
}
Card incomeExpenseStatus(List<Entries> entries) {
return Card(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Transaction Summary",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
Container(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
"Income",
style: TextStyle(),
),
const Text(
"Rs. 60000",
style: TextStyle(
color: Colors.green,
fontSize: 16,
fontWeight: FontWeight.bold),
),
Container(
width: 1,
height: 20,
color: Colors.black,
),
const Text(
"Expenses",
),
const Text(
"Rs. 100000",
style: TextStyle(
color: Colors.red,
fontSize: 16,
fontWeight: FontWeight.bold),
),
],
),
),
],
),
),
);
}
Widget transactionSection(List<Entries> entries) {
int? totalAmt;
return Card(
child: Column(
children: [
const SizedBox(height: 5),
Text(
"Transactions count : ${entries.length}",
style: const TextStyle(fontSize: 10, color: Colors.red),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 10),
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: entries.length,
itemBuilder: (context, index) {
var transaction = entries[index];
DateTime d = DateTime.parse(transaction.entryLog);
return Card(
child: ListTile(
//*?How icon color works
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => TransactionDetailScreen(
index: transaction)),
),
);
},
leading: CircleAvatar(
child: Center(
child: Icon(
getCategoryWiseIcon(
transaction.details!.category.toString()),
),
),
),
title: Text(transaction.details!.category.toString()),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(transaction.details!.remarks.toString()),
Text("$d"),
],
),
trailing: transaction.details!.isIncome == true
? Text("IN",
style:
TextStyle(color: ColorTheme().greenColor))
: Text("OUT",
style: TextStyle(
color: ColorTheme().primaryColor))),
);
}),
),
),
],
),
);
}
int activeDay = 1;
#override
void initState() {
activeDay = DateTimeExtractor().getDayAsInteger(activeDay);
super.initState();
}
Widget weekTabs(size, index, day) {
log('Active month:$activeDay');
return GestureDetector(
onTap: () {
setState(() {
activeDay = index;
});
},
child: Row(
children: [
Column(
children: [
Text(
day['label'],
style: TextStyle(
fontSize: 12,
color: activeDay == index
? ColorTheme().primaryColor
: ColorTheme().blackColor.withOpacity(0.8),
fontWeight: activeDay == index
? FontWeight.w500
: FontWeight.normal),
),
const SizedBox(height: 5),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: activeDay == index
? ColorTheme().primaryColor
: ColorTheme().whiteColor,
shape: BoxShape.circle,
border: Border.all(color: ColorTheme().primaryColor),
),
child: Center(
child: Text(
day['day'],
style: TextStyle(
fontSize: 12,
color: activeDay != index
? ColorTheme().primaryColor
: ColorTheme().whiteColor,
),
),
),
),
],
),
const SizedBox(width: 20),
],
),
);
}
}
This is my Entres model class
class Entries {
String? addedBy;
Details? details;
String? entryID;
dynamic entryLog;
String? gaadiID;
Entries({
this.addedBy = "",
this.details,
this.entryID = "",
this.entryLog,
this.gaadiID = "",
});
factory Entries.fromJson(Map<String, dynamic> json) =>
_$EntriesFromJson(json);
Map<String, dynamic> toJson() => _$EntriesToJson(this);
Entries _$EntriesFromJson(Map<String, dynamic> json) => Entries(
addedBy: json['addedBy'] as String? ?? "",
details: json['details'] == null
? null
: Details.fromJson(json['details'] as Map<String, dynamic>),
entryID: json['entryID'] as String? ?? "",
entryLog: json['entryLog'].toString(),
gaadiID: json['gaadiID'] as String? ?? "",
);
Map<String, dynamic> _$EntriesToJson(Entries instance) => <String, dynamic>{
'addedBy': instance.addedBy,
'details': instance.details,
'entryID': instance.entryID,
'entryLog': instance.entryLog.toString(),
'gaadiID': instance.gaadiID,
};
}
If you need any more info then please feel free to ask .

Flutter- click is responding to every item in listview.builder

I am trying to create a list of items in flutter with listView.builder, i am also using using elevatedButton in my itemBuilder.
i applied setState in button
i want to change value of single item only
but that is applying to every value in list
here is my code
import 'dart:developer';
import 'package:counter_button/counter_button.dart';
import 'package:flutter/material.dart';
import 'package:fooddeliveryapp/apis.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'models/restrauntmenu.dart';
class RestrauntPage extends StatefulWidget {
final String restrauntId;
final String restrauntName;
final String restrauntType;
final String restrauntApproxBill;
final String restrauntTagline;
const RestrauntPage(
{Key? key,
required this.restrauntId,
required this.restrauntType,
required this.restrauntApproxBill,
required this.restrauntTagline,
required this.restrauntName})
: super(key: key);
#override
State<RestrauntPage> createState() => _RestrauntPageState();
}
class _RestrauntPageState extends State<RestrauntPage> {
int _counterValue = 1;
bool itemAdded = false;
late Future<List<RestrauntMenu>> futureRestrauntMenu;
Future<List<RestrauntMenu>> fetchRestrauntMenu() async {
String restrauntId = widget.restrauntId;
final response = await http.get(Uri.parse(menuApi(restrauntId)));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<RestrauntMenu>((json) => RestrauntMenu.fromMap(json))
.toList();
} else {
throw Exception('Failed to load album');
}
}
addToCartButton(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) {
return ElevatedButton(
clipBehavior: Clip.antiAliasWithSaveLayer,
style: ButtonStyle(
elevation: MaterialStateProperty.all(
6,
),
backgroundColor: MaterialStateProperty.all(Colors.white),
),
onPressed: () {
addToCart(
itemname: itemname,
itemprice: itemprice,
restrauntName: restrauntName,
usermob: usermob,
itemCount: itemCount);
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'ADD TO CART',
style: TextStyle(
color: Colors.green,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
);
}
counterButton() {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue = val;
});
},
count: _counterValue,
countColor: Colors.green,
buttonColor: Colors.black,
progressColor: Colors.black,
),
);
}
Future addToCart(
{required String? itemname,
required String? itemprice,
required int? itemCount,
required String? usermob,
required String? restrauntName}) async {
itemCount = _counterValue;
var url = addToCartApi(
itemname: itemname,
itemprice: itemprice,
itemCount: itemCount,
usermob: usermob,
restrauntName: restrauntName);
var response = await http.get(
Uri.parse(url),
);
if (response.statusCode == 200) {
setState(() {
itemAdded = true;
});
} else {
return false;
}
}
#override
void initState() {
futureRestrauntMenu = fetchRestrauntMenu();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
foregroundColor: Colors.black,
elevation: 0,
backgroundColor: Colors.white,
title: const Text('Restraunt Name'),
),
body: SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.restrauntName,
style: const TextStyle(
color: Colors.black,
fontSize: 24,
fontWeight: FontWeight.w900,
),
),
// const SizedBox(height: 4),
Text(
widget.restrauntType,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.normal,
),
),
Text(
widget.restrauntTagline,
style: const TextStyle(
color: Colors.black87,
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
const SizedBox(
height: 6,
),
Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: TextSpan(
children: [
const WidgetSpan(
child: Icon(
Icons.currency_rupee,
size: 16,
color: Color.fromARGB(255, 45, 174, 49),
),
),
TextSpan(
text: widget.restrauntApproxBill,
style: const TextStyle(
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
],
),
const Spacer(),
Container(
decoration: BoxDecoration(
color: const Color.fromARGB(255, 49, 171, 53),
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RichText(
text: const TextSpan(
children: [
TextSpan(
text: '3.6',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
WidgetSpan(
child: Icon(
Icons.star,
color: Colors.white,
size: 18,
),
),
],
),
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.03,
),
],
),
const SizedBox(
height: 12,
),
Expanded(
child: FutureBuilder<List<RestrauntMenu>>(
future: futureRestrauntMenu,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return ExpansionTile(
initiallyExpanded: true,
childrenPadding: const EdgeInsets.all(8),
title: Text(
snapshot.data![index].catname!,
style: const TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
),
children: [
Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
snapshot.data![index].itemname!,
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemPrice!,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 4,
),
Text(
snapshot.data![index].itemDescription!,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
),
),
],
),
const Spacer(),
Stack(
alignment: Alignment.bottomCenter,
children: [
Padding(
padding:
const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius:
BorderRadius.circular(10),
child: FittedBox(
child: Container(
height: MediaQuery.of(context)
.size
.height *
0.22,
width: MediaQuery.of(context)
.size
.width *
0.4,
decoration: BoxDecoration(
color: Colors.red,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'http://www.jfamoslogistics.com/images/${snapshot.data![index].itemimage!}',
),
),
),
),
),
),
),
Align(
alignment: Alignment.topRight,
child: itemAdded
? counterButton()
: addToCartButton(
itemprice: snapshot
.data![index].itemPrice,
itemname: snapshot
.data![index].itemname,
itemCount: _counterValue,
restrauntName:
widget.restrauntName,
usermob: '9354954343',
))
],
)
],
),
],
);
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
],
),
),
),
);
}
}
please check and help me
please let me know if i am missing something or making some mistake in code
i have tried google everywhere but nothing works
thanks in advance
As Giseppe Colucci described, you are using a single counter variable for a list . You can follow the simple approach of using list. On State
int _counterValue = 1; will be replaced with List<int> _counterValue = []
After getting data initialize the list with default value.
if (snapshot.hasData) {
_counterValue =List.generate(snapshot.data!.length, (index) => 1); // you might prefer default value as 0 instead of 1
As for the counter button method we need to update specific index, therefore we will pass index here
counterButton(int index) {
return Container(
decoration: const BoxDecoration(color: Colors.white),
child: CounterButton(
loading: false,
onChange: (int val) {
setState(() {
_counterValue[index] = val;
});
},
count: _counterValue[index],
Now whenever we use this counterButton method we need to pass index and here we get index from listview.
child: itemAdded
? counterButton(index)
: addToCartButton(
That is because your itemAdded bool is only one, for every item in the list, you should make a map, like this:
{'id':true}
where id is the restaurant menu item, and true is whenever the item is selected or not.
If this is too hard for you, just use a simple list.

Error in flutter : <asynchronous suspension>

I want to show a dialog box after product add successfully but when I clicking on Add To Cart Button then I am getting that type of error which is in image.
This dialog box want to show using httpException, in product_detailpage.dart page where i use this httpExcetion there are i use dotted line.
This is my cart_api.dart page
import 'dart:convert';
import 'package:hospital/CartPage/Cart_Api/cart_http_exception.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
Future add_to_cart_fn(
String quantity, String plistId, String uid, String sid) async {
var url = Uri.parse(
'$ecommerceBaseUrl/addToCartApi.php?a2rTokenKey=$a2rTokenKey&action=addToCart&uid=60daaedd3b9f8751161');
print('add_to_cart_url:' + url.toString());
final response = await http.post(url, headers: {
"Accept": "Application/json"
}, body: {
"quantity": quantity,
"plistId": plistId,
"uid": uid,
"sid": sid,
});
print("ae" + response.body);
final convertderDatatoJson = jsonDecode(response.body);
try {
if (convertderDatatoJson['status'] == "true") {
print('status' + convertderDatatoJson['status']);
print('msg' + convertderDatatoJson['msg']);
throw HttpException(convertderDatatoJson['msg']);
}
} catch (e) {
throw e;
}
return convertderDatatoJson;
}
this is my httpException.dart page
class HttpException implements Exception {
final msg;
HttpException(this.msg);
#override
String toString() {
// TODO: implement toString
return msg;
}
}
This is my product_detailPage.dart page,
import 'dart:convert';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter/material.dart';
import 'package:hospital/CartPage/Cart_Api/cart_api.dart';
import 'package:hospital/CartPage/Cart_Api/cart_http_exception.dart';
import 'package:hospital/CartPage/pages/cartPage.dart';
import 'package:hospital/Drawer/dropdown_menu.dart';
import 'package:hospital/ProductDetailsPage/product_detailPage.dart';
import 'package:hospital/ProductDetailsPage/related_product_page.dart';
import 'package:hospital/SecondSection/Medicine/medicine_page.dart';
import 'package:hospital/constant.dart';
import 'package:hospital/customApiVariable.dart';
import 'package:http/http.dart' as http;
import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart';
class DetailPage extends StatefulWidget {
final plistId;
const DetailPage({Key key, this.plistId}) : super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
final GlobalKey<FormState> _formKey = GlobalKey();
int quantity = 1;
var response;
var detailPageApi;
#override
void initState() {
super.initState();
fetchData(widget.plistId);
}
fetchData(var consultWithDoctor) async {
a2rTokenKey=carpet1234');
var api = Uri.parse(
'$ecommerceBaseUrl/productListApi.php?a2rTokenKey=$a2rTokenKey&plistId=${widget.plistId}');
response = await http.get(
api,
);
print("detailPageApi " + api.toString());
print("detailPageBody " + response.body);
// in double quotes drink is key value of json
detailPageApi = jsonDecode(response.body);
print("detailPagelist " + detailPageApi.toString());
// return doctorDetailsApi;
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kGreen,
title: Text(
"Details",
style: TextStyle(fontStyle: FontStyle.italic),
),
actions: [
IconButton(
icon: Icon(Icons.shopping_cart),
// onPressed: () => print("open cart"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Cartpage()),
);
},
),
DropDownMenu(),
],
),
body: Container(
child: response != null
? ListView.builder(
// itemCount: categoryApi.length.clamp(0, 3),//THis is for showed minimun length of item listview.builder flutter
itemCount: detailPageApi.length.clamp(0, 1),
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
var details = detailPageApi[index];
if (details['num'] == 0) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
);
}
return Column(
children: <Widget>[
Hero(
tag: "1",
child: SizedBox(
height: 300.0,
width: 300.0,
child: Carousel(
boxFit: BoxFit.cover,
autoplay: false,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 800),
dotSize: 6.0,
dotIncreasedColor: Colors.black,
dotBgColor: Colors.transparent,
// dotPosition: DotPosition.topRight,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: [
NetworkImage(details['pImgImg']),
],
),
),
),
SizedBox(
height: 50,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Name :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productName'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Details :",
style: TextStyle(
fontSize: 18,
height: 1.5,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Flexible(
child: Text(
// widget.details,
details['productDescription'],
style: TextStyle(
fontSize: 17,
height: 1.5,
fontWeight: FontWeight.w500),
),
),
],
),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Row(
children: <Widget>[
Text(
"Price :",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
Text(
// "Rs " + widget.pPromotionPrice,
"Rs 55.0",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Text(
// "Rs " + widget.pPrice,
"Rs 100",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
// color: warning,
decoration: TextDecoration.lineThrough),
)
],
)
],
),
),
SizedBox(
height: 25,
),
Padding(
padding: const EdgeInsets.only(right: 20, left: 20),
child: Row(
children: <Widget>[
Text(
"Qty :",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
),
SizedBox(
width: 20,
),
Row(
children: <Widget>[
InkWell(
onTap: () {
if (quantity > 1) {
setState(() {
quantity = --quantity;
});
}
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.minus,
size: 15,
),
),
),
SizedBox(
width: 15,
),
Text(
quantity.toString(),
style: TextStyle(fontSize: 16),
),
SizedBox(
width: 15,
),
InkWell(
onTap: () {
setState(() {
quantity = ++quantity;
});
// minus here
},
child: Container(
width: 25,
height: 25,
decoration: BoxDecoration(
// border: Border.all(color: primary),
shape: BoxShape.circle),
child: Icon(
LineIcons.plus,
size: 15,
),
),
),
],
)
],
),
),
SizedBox(
height: 50,
),
InkWell(
onTap: () async {
---------------------------------------------
//here show my msg using dialog box
try {} on HttpException catch (e) {
print('hiii');
var errorMessage = 'Authentication Failed';
if (e.toString().contains(
'Product Succesfully Added to Cart')) {
errorMessage =
'Product Succesfully Added to Cart';
print(errorMessage);
_showerrorDialog(errorMessage);
}
} catch (error) {
var errorMessage = 'Please try again later';
_showerrorDialog(errorMessage);
}
------------------------------------------------
var qty = quantity.toString();
var plistId = widget.plistId;
print('pplistid' + plistId);
var uid = var_uid.toString();
var sid = var_sid.toString();
print('uuid' + uid);
print('ssid' + sid);
var response =
await add_to_cart_fn(qty, plistId, uid, sid);
print("rsp: " + response['status']);
},
// },
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Container(
height: 45,
width: double.infinity,
decoration: BoxDecoration(
color: kGreen,
borderRadius: BorderRadius.circular(30)),
child: Center(
child: Text(
"ADD TO CART",
style: TextStyle(
color: kWhite,
fontSize: 20,
),
),
),
),
),
),
SizedBox(height: 20.0),
// SomeMedicinePage(),
RelatedProductPage(plistId: widget.plistId)
],
);
})
: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
),
),
),
);
}
void _showerrorDialog(String message) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(
'An Error Occurs',
style: TextStyle(color: Colors.blue),
),
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () => Navigator.of(context, rootNavigator: true).pop())
],
),
);
}
}
Found this answer (not mine):
is not an indication of a problem, it just indicates that code execution is not synchronous code executed line-by-line, but instead a callback from a completed Future started at some position in the callstack
Source :
https://stackoverflow.com/questions/60658945/asynchronous-suspension-in-stacktrace-output-in-flutter#:~:text=is%20not%20an,some%20position%20in%20the%20callstack.
wrap that api or platform specific code inside a try and catch block on catch (e){ do your stuff here error handling }

How To Dynamically add Dropdown buttons or delete dropdown(s) in listview with flutter Web?

i have created a page where a user who will click a title to edit the contents and can add and delete devices that the article is attached to,
but i could not figure it out on how to program the drop down dynamically, to add more drop downs when a user press the add device button,
the additional function they want me to add as well is on the Dropdown list, when they select 'NONE' it should remove that dropdown as well,
i am planning to use mysql,xampp or sqlite for my database if im done with the UI,
import 'package:flutter/material.dart';
import 'package:surveyadminpanel/Contents/tabbar.dart';
import 'package:surveyadminpanel/widgets/button.dart';
import 'package:surveyadminpanel/widgets/simplewidgets.dart';
import 'homepage.dart';
import 'dart:ui';
class Item {
Item(this.name);
String name;
}
class editsurvey extends StatefulWidget {
#override
_editsurveyState createState() => _editsurveyState();
}
class _editsurveyState extends State<editsurvey>{
int surveyquestionnum = 1;
int surveyquestiontotal = 1;
List<Item> selectedUser = [null, null];
List<Item> selecteddata = [null, null];
List<Item> users;
int linkdevices = 1;
String dropdownvalue= "SELECT FROM DROPDOWN";
List data = [
'Sample Data 1',
'Sample Data 2',
'Sample Data 3',
'Sample Data 4',
'Sample Data 5',
'Sample Data 6',
];
#override
void initState() {
super.initState();
users = <Item>[
Item('Sample device 1'),
Item('Sample device 2'),
Item('Sample device 3'),
Item('Sample device 4'),
];
}
#override
Widget _dropdownbutton (List<Item> userlist, int index){
return Container(
padding: EdgeInsets.all(1),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(
Radius.circular(15.0) //
),
),
child: DropdownButton<Item>(
underline: SizedBox(),
isExpanded: true,
icon: Icon(Icons.arrow_drop_down),
hint: Text(" $dropdownvalue"),
value: selectedUser[index],
onChanged: (Item Value) {
setState(() {
selectedUser[index] = Value;
});
},
items: userlist.map((Item user) {
return DropdownMenuItem<Item>(
value: user,
child: Row(
children: <Widget>[
SizedBox(width: 10,),
Text(
user.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList(),
),
);
}
Widget _text(texthere,bold,size,color){
return Text(texthere,style: TextStyle(fontWeight: bold,fontSize: size,color: color),overflow: TextOverflow.ellipsis,maxLines: 1);
}
Widget _logo(){
return InkWell(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => admincontent()),
);
},
child: Container(width: 500,height: 200,child: Image.asset("images/v2.jpg")));
}
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Padding(padding: EdgeInsets.only(left: 30),
child: RichText(
text: TextSpan(
text: 'Good Morning Welcome to Sample:',
style: TextStyle(
color: Colors.blueAccent, fontSize: 18),
children: <TextSpan>[
TextSpan(text: usernametitle,
style: TextStyle(
color: Colors.black, fontSize: 18),
)
]
),
)
),
elevation: 1,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: _logo(),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.notifications),
color: Colors.blueAccent,
tooltip: 'Show Notification',
onPressed: () {
},
),
IconButton(
color: Colors.lightGreen,
icon: const Icon(Icons.account_circle),
tooltip: 'Check your Profile',
onPressed: () {
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_text("EDIT SURVEY", FontWeight.bold, 20,Colors.blue),
roundedRectButton("BACK", signInGradients),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: screenWidth/1.6,
height: screenHeight/1.6,
decoration: BoxDecoration(
color: Colors.orange[200],
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_text("SURVEY TITLE", FontWeight.bold, 17,Colors.white),
_text(data[0], FontWeight.bold, 19, Colors.black),
_text("DATE CREATED", FontWeight.bold, 17,Colors.white),
_text(data[1], null, 19, Colors.black),
_text("CURRENT STATUS", FontWeight.bold, 17,Colors.white),
_text(data[2], null, 19, Colors.black),
_text("LANGUAGE VERSION", FontWeight.bold, 17,Colors.white),
_text(data[3], null, 19, Colors.black),
_text("NUMBERS OF ASSESSORS", FontWeight.bold, 17,Colors.white),
_text(data[4], null, 19, Colors.black),
_text("TOTAL RENDERED SURVEYS", FontWeight.bold, 17,Colors.white),
_text(data[5], null, 19, Colors.black),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: (){
},
child: Container(width: 100,height: 50,child: Text("EDIT SURVEY")),
),
_text("LINKED DEVICES : $linkdevices", FontWeight.bold, 17,Colors.white),
],
)
],
),
)
),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid
)
),
width: screenWidth/1.6,
height: screenHeight/1.6,
child: Column(
children: <Widget>[
_text("DEVICES PINNED", FontWeight.bold, 20,Colors.blue),
ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index){
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
child: roundedRectButton("ADD DEVICE", signInGradients),
onTap: (){
},
),
InkWell(
child: roundedRectButton("CLEAR ALL DEVICE", signInGradients),
onTap: (){
},
),
],
),
],
),
),
],
)
],
),
),
),
);
}
}
The Plan
The Result
im still trying to figure this out, but if someone can give me a lift,, im gonna be very thankful to who can help me out here ,,
You can copy paste run full code below
You can increase linkdevices and selectedUser
code snippet
List<Item> selectedUser = [null];
...
InkWell(
child: Text("ADD DEVICE"),
onTap: () {
selectedUser.add(null);
linkdevices ++;
setState(() {
});
working demo
full code
import 'package:flutter/material.dart';
class Item {
Item(this.name);
String name;
}
class editsurvey extends StatefulWidget {
#override
_editsurveyState createState() => _editsurveyState();
}
class _editsurveyState extends State<editsurvey> {
int surveyquestionnum = 1;
int surveyquestiontotal = 1;
List<Item> selectedUser = [null];
List<Item> selecteddata = [null, null];
List<Item> users;
int linkdevices = 1;
String dropdownvalue = "SELECT FROM DROPDOWN";
List data = [
'Sample Data 1',
'Sample Data 2',
'Sample Data 3',
'Sample Data 4',
'Sample Data 5',
'Sample Data 6',
];
#override
void initState() {
super.initState();
users = <Item>[
Item('Sample device 1'),
Item('Sample device 2'),
Item('Sample device 3'),
Item('Sample device 4'),
];
}
#override
Widget _dropdownbutton(List<Item> userlist, int index) {
return Container(
padding: EdgeInsets.all(1),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(Radius.circular(15.0) //
),
),
child: DropdownButton<Item>(
underline: SizedBox(),
isExpanded: true,
icon: Icon(Icons.arrow_drop_down),
hint: Text(" $dropdownvalue"),
value: selectedUser[index],
onChanged: (Item Value) {
print(Value.toString());
print(index);
setState(() {
selectedUser[index] = Value;
});
},
items: userlist.map((Item user) {
return DropdownMenuItem<Item>(
value: user,
child: Row(
children: <Widget>[
SizedBox(
width: 10,
),
Text(
user.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList(),
),
);
}
Widget _text(texthere, bold, size, color) {
return Text(texthere,
style: TextStyle(fontWeight: bold, fontSize: size, color: color),
overflow: TextOverflow.ellipsis,
maxLines: 1);
}
Widget _logo() {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => admincontent()),
);
},
child: Container(
width: 500, height: 200, child: Image.asset("images/v2.jpg")));
}
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Padding(
padding: EdgeInsets.only(left: 30),
child: RichText(
text: TextSpan(
text: 'Good Morning Welcome to Sample:',
style: TextStyle(color: Colors.blueAccent, fontSize: 18),
children: <TextSpan>[
TextSpan(
text: "usernametitle",
style: TextStyle(color: Colors.black, fontSize: 18),
)
]),
)),
elevation: 1,
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
leading: _logo(),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.notifications),
color: Colors.blueAccent,
tooltip: 'Show Notification',
onPressed: () {},
),
IconButton(
color: Colors.lightGreen,
icon: const Icon(Icons.account_circle),
tooltip: 'Check your Profile',
onPressed: () {},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
_text("EDIT SURVEY", FontWeight.bold, 20.0, Colors.blue),
//roundedRectButton("BACK", signInGradients),
Text("BACK"),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: screenWidth / 1.6,
height: screenHeight / 1.6,
decoration: BoxDecoration(
color: Colors.orange[200],
borderRadius:
new BorderRadius.all(new Radius.circular(20.0)),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_text("SURVEY TITLE", FontWeight.bold, 17.0,
Colors.white),
_text(data[0], FontWeight.bold, 19.0, Colors.black),
_text("DATE CREATED", FontWeight.bold, 17.0,
Colors.white),
_text(data[1], null, 19.0, Colors.black),
_text("CURRENT STATUS", FontWeight.bold, 17.0,
Colors.white),
_text(data[2], null, 19.0, Colors.black),
_text("LANGUAGE VERSION", FontWeight.bold, 17.0,
Colors.white),
_text(data[3], null, 19.0, Colors.black),
_text("NUMBERS OF ASSESSORS", FontWeight.bold, 17.0,
Colors.white),
_text(data[4], null, 19.0, Colors.black),
_text("TOTAL RENDERED SURVEYS", FontWeight.bold,
17.0, Colors.white),
_text(data[5], null, 19.0, Colors.black),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: () {},
child: Container(
width: 100,
height: 50,
child: Text("EDIT SURVEY")),
),
_text("LINKED DEVICES : $linkdevices",
FontWeight.bold, 17.0, Colors.white),
],
)
],
),
)),
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid)),
width: screenWidth / 1.6,
height: screenHeight / 1.6,
child: Column(
children: <Widget>[
_text("DEVICES PINNED", FontWeight.bold, 20.0,
Colors.blue),
ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
child: Text("ADD DEVICE"),
onTap: () {
selectedUser.add(null);
linkdevices ++;
setState(() {
});
/*listWidget.add( ListView.separated(
shrinkWrap: true,
itemCount: linkdevices,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: _dropdownbutton(users, index),
);
},
separatorBuilder: (context, index) => Container(height: 10),
));
setState(() {
});*/
},
),
InkWell(
child: Text("CLEAR ALL DEVICE"),
onTap: () {},
),
],
),
],
),
),
],
)
],
),
),
),
);
}
}
class admincontent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container();
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: editsurvey(),
);
}
}