![](/img/trans.png)
[英]type 'List<Map<String, dynamic>>' is not a subtype of type 'Map<dynamic, dynamic>'
[英]Error: type '() => Map<String, dynamic>?' is not a subtype of type 'Map<String, dynamic>?'
我正在尝试获取条形码来扫描项目并从 Cloud firestore 数据库中检索项目。 该应用程序旨在随后将项目显示在主页上。 但我一直有同样的错误。 我试图将其更改为 Map<Dynamic, Dynamic>。 我还尝试将其从不是 null Map<String, dynamic> 没有问号中删除。 所有 flutter 库以及 pubspec 都是最新的。
下面的代码是我的主页
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/services.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
Map<String, dynamic>? mapProducts = {};
//Initialize
@override
void initState() {
if (userProfile.containsKey("Unordered Products")) {
mapProducts = userProfile["Unordered Products"];
}
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
double size =
MediaQuery.of(context).size.width < MediaQuery.of(context).size.height
? MediaQuery.of(context).size.width
: (!kIsWeb)
? MediaQuery.of(context).size.height
: MediaQuery.of(context).size.height / 2;
//For Refreshing the theme
if (userProfile.containsKey("Theme")) {
myAppTheme = userProfile["Theme"] == "Light Theme"
? getMainThemeWithBrightness(context, Brightness.light)
: getMainThemeWithBrightness(context, Brightness.dark);
}
MobileScannerController cameraController = MobileScannerController();
return SafeArea(
child: Scaffold(
key: scaffoldKey,
backgroundColor: myAppTheme?.scaffoldBackgroundColor,
appBar: getAppBar(
scaffoldKey: scaffoldKey,
context: context,
strAppBarTitle: "Spar Store",
showBackButton: false,
),
//drawer
drawer: getDrawer(context, scaffoldKey),
floatingActionButton: FloatingActionButton(
backgroundColor: myAppTheme?.primaryColor,
onPressed: () async {
String? barcode = await scan();
if (barcode != null && barcode != "") {
if (mapProducts!.containsKey(barcode)) {
//Increase count
setState(() {
mapProducts![barcode] = ++mapProducts![barcode];
});
} else {
//Add a new product
setState(() {
mapProducts![barcode] = 1;
});
}
userProfile["Unordered Products"] = mapProducts;
//Update the new Unordered Products list to the Firebase CLoud Firestpre
await authService.setData();
}
},
child: Icon(Icons.add, color: myAppTheme?.iconTheme.color),
),
//Body
body: mapProducts != null && mapProducts!.length > 0
? Column(
children: <Widget>[
//Products in Cart List
getUnorderedProducts(size),
//Final invoice
getInvoice(size),
//Checkout Button
getCheckoutButton(size),
],
)
: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
"assets/images/empty-cart.png",
fit: BoxFit.fitWidth,
),
Text(
"No Items Added.\nPlease Add items by scanning them",
style: myAppTheme?.textTheme.caption,
textAlign: TextAlign.center,
),
],
),
),
),
);
}
//Get the list of all the Orders still in Cart
getUnorderedProducts(double size) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.7,
child: ListView.builder(
itemCount: mapProducts!.length,
itemBuilder: (context, index) {
return FutureBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null || snapshot.hasData == false) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
myAppTheme!.primaryColor),
strokeWidth: 5,
),
);
} else {
Map<String, dynamic>? mapProduct = snapshot.data;
return GestureDetector(
child: Card(
elevation: myAppTheme?.cardTheme.elevation,
color: myAppTheme?.cardTheme.color,
shape: myAppTheme?.cardTheme.shape,
child: Row(
children: <Widget>[
mapProduct!.containsKey("photo url")
? ClipRRect(
borderRadius: BorderRadius.circular(15),
child: SizedBox(
width: 120,
child: Image.network(
mapProduct["photo url"][0])))
: Icon(
Icons.category,
color: myAppTheme?.iconTheme.color,
),
SizedBox(
width: size - 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
//Title
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
mapProduct["name"],
style: myAppTheme?.textTheme.caption,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right,
),
),
//Model
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(mapProduct["model"],
style: myAppTheme?.textTheme.bodyText1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right),
),
//Discount
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Discount: ${mapProduct["discount"]}%",
style: myAppTheme?.textTheme.bodyText1
?.copyWith(
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right),
),
//Price
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Price: ${mapProduct["price"]}",
style: myAppTheme?.textTheme.bodyText1
?.copyWith(
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.right),
),
//Quantity
Container(
padding: const EdgeInsets.all(8.0),
height: 60,
child: StepperTouch(
initialValue:
mapProducts?.values.elementAt(index),
direction: Axis.horizontal,
withSpring: true,
primaryColor:
myAppTheme?.colorScheme.secondary,
textColor:
myAppTheme?.textTheme.bodyText1?.color,
onChanged: (int value) {
if (value == 0) {
setState(() {
mapProducts?.remove(mapProducts?.keys
.elementAt(index));
});
} else if (value > 0) {
setState(() {
mapProducts![mapProducts!.keys
.elementAt(index)] = value;
});
}
userProfile["Unordered Products"] =
mapProducts;
},
),
),
],
),
),
],
),
),
//Open
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ViewProductScreen(mapProduct)),
);
},
);
}
},
future: getProduct(mapProducts!.keys.elementAt(index)),
);
}),
);
}
//Get the Total Price and the Total discount
getInvoice(double size) {
return FutureBuilder(
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot == null ||
snapshot.data == null ||
snapshot.hasData == false) {
return Center(
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(myAppTheme!.primaryColor),
strokeWidth: 5,
),
);
} else {
Map mapProduct = snapshot.data;
double dbTotalDiscount = mapProduct["discount"],
dbTotalPrice = mapProduct["price"];
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
//Total Price
Padding(
padding: const EdgeInsets.fromLTRB(0, 5, 10, 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
"Total Price: ",
style: myAppTheme?.textTheme.bodyText1,
overflow: TextOverflow.ellipsis,
),
Text(
dbTotalPrice.toString(),
style: myAppTheme?.textTheme.bodyText1,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
);
}
},
future: getInvoiceDetails(),
);
}
getInvoiceDetails() async {
double dbTotalDiscount = 0.0, dbTotalPrice = 0.0;
//Loop through all the products to get the Discount and the Price
await Future.forEach(mapProducts!.keys, (key) async {
String strProductID = key;
Map<String, dynamic>? mapProduct =
(await getProduct(strProductID)) as Map<String, dynamic>?;
if (mapProduct!.containsKey("discount")) {
dbTotalDiscount += double.tryParse(
(mapProduct["discount"] * mapProducts![key]).toString())!;
}
if (mapProduct.containsKey("price")) {
dbTotalPrice += double.tryParse(
(mapProduct["price"] * mapProducts![key]).toString())!;
}
// print("discount: " + dbTotalDiscount.toString());
// print("price: " + dbTotalPrice.toString());
});
return {"discount": dbTotalDiscount, "price": dbTotalPrice};
}
//Get Checkout button
getCheckoutButton(double size) {
return ButtonTheme(
minWidth: double.infinity,
child: Padding(
padding: const EdgeInsets.fromLTRB(80, 20, 80, 10),
child: primaryRaisedButton(
context: context,
text: "Checkout now",
color: myAppTheme?.primaryColor,
onPressed: () async {
//Go to Checkout
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => CheckoutScreen()),
);
setState(() {
//Refresh the UI after returning back from the Checkout screen
mapProducts = userProfile["Unordered Products"];
});
},
),
),
);
}
//=================================================================================
//Get details of product
Future<Map<String, dynamic>? Function()> getProduct(String barcode) async {
return (await FirebaseFirestore.instance
.collection("Products")
.doc(barcode)
.get())
.data;
}
//Scan QR code
Future<String?> scan() async {
try {
String barcode = (await FlutterBarcodeScanner.scanBarcode(
'#ff6666', 'Cancel', true, ScanMode.QR));
return barcode;
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.cameraAccessDenied) {
showSnackBar(
scaffoldKey: scaffoldKey,
text: "The user did not grant the camera permission!",
buttonText: '',
onPressed: () {});
} else {
showSnackBar(
scaffoldKey: scaffoldKey,
text: "Unknown error: $e",
buttonText: '',
onPressed: () {});
}
return null;
} on FormatException {
showSnackBar(
scaffoldKey: scaffoldKey,
text:
'null (User returned using the "back"-button before scanning anything. Result)',
buttonText: '',
onPressed: () {});
} catch (e) {
showSnackBar(
scaffoldKey: scaffoldKey,
text: "Unknown error: $e",
buttonText: '',
onPressed: () {});
}
return null;
}
}
如果有人能提供帮助会很棒,因为我是初学者,而且是针对学校项目的。
用这个替换你的getProduct()
方法:
Future<Map<String, dynamic>?> getProduct(String barcode) async {
return (await FirebaseFirestore.instance
.collection("Products")
.doc(barcode)
.get())
.data() ;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.