I keep on getting this problem:
Unhandled Exception: Error: Could not find the correct Provider above this HomeScreen Widget
Since I am trying to implement Cart Item Counter, there is this bug.
Here is my code:
Main.dart
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (c) => CartItemCounter()),
ChangeNotifierProvider(create: (c) => TotalAmount()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Users App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MySplashScreen(),
),
);
}
}
Below is my App Bar, This is where i send users to Cart:
class MyAppBar extends StatefulWidget with PreferredSizeWidget {
final PreferredSizeWidget? bottom;
final String? sellerUID;
MyAppBar({this.bottom, this.sellerUID});
@override
_MyAppBarState createState() => _MyAppBarState();
@override
Size get preferredSize => bottom == null
? Size(56, AppBar().preferredSize.height)
: Size(56, 80 + AppBar().preferredSize.height);
}
class _MyAppBarState extends State<MyAppBar> {
@override
Widget build(BuildContext context) {
return AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
//send user to cart screen
Navigator.push(
context,
MaterialPageRoute(
builder: (c) =>
CartScreen(sellerUID: widget.sellerUID)));
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
);
}
}
Following is My Cart Screen:
I want to display cart items with quantity number
class CartScreen extends StatefulWidget {
final String? sellerUID;
CartScreen({this.sellerUID});
@override
_CartScreenState createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
List<int>? separateItemQuantityList;
num totalAmount = 0;
@override
void initState() {
super.initState();
totalAmount = 0;
Provider.of<TotalAmount>(context, listen: false).displayTotalAmount(0);
separateItemQuantityList = separateItemQuantities();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.cyan,
Colors.amber,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
),
leading: IconButton(
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
},
),
title: const Text(
"iFood",
style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
),
centerTitle: true,
automaticallyImplyLeading: true,
actions: [
Stack(
children: [
IconButton(
icon: const Icon(
Icons.shopping_cart,
color: Colors.cyan,
),
onPressed: () {
print("clicked");
},
),
Positioned(
child: Stack(
children: [
const Icon(
Icons.brightness_1,
size: 20.0,
color: Colors.green,
),
Positioned(
top: 3,
right: 4,
child: Center(
child: Consumer<CartItemCounter>(
builder: (context, counter, c) {
return Text(
counter.count.toString(),
style: const TextStyle(
color: Colors.white, fontSize: 12),
);
},
),
),
),
],
),
),
],
),
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const SizedBox(
width: 10,
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Clear Cart",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.clear_all),
onPressed: () {
clearCartNow(context);
Navigator.push(context,
MaterialPageRoute(builder: (c) => const MySplashScreen()));
Fluttertoast.showToast(msg: "Cart has been cleared.");
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: FloatingActionButton.extended(
label: const Text(
"Check Out",
style: TextStyle(fontSize: 16),
),
backgroundColor: Colors.cyan,
icon: const Icon(Icons.navigate_next),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (c) => AddressScreen(
// totalAmount: totalAmount.toDouble(),
// sellerUID: widget.sellerUID,
// ),
// ),
// );
},
),
),
],
),
body: CustomScrollView(
slivers: [
//overall total amount
SliverPersistentHeader(
pinned: true, delegate: TextWidgetHeader(title: "My Cart List")),
SliverToBoxAdapter(
child: Consumer2<TotalAmount, CartItemCounter>(
builder: (context, amountProvider, cartProvider, c) {
return Padding(
padding: const EdgeInsets.all(8),
child: Center(
child: cartProvider.count == 0
? Container()
: Text(
"Total Price: " + amountProvider.tAmount.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
);
}),
),
//display cart items with quantity number
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("items")
.where("itemID", whereIn: separateItemIDs())
.orderBy("publishedDate", descending: true)
.snapshots(),
builder: (context, snapshot) {
return !snapshot.hasData
? SliverToBoxAdapter(
child: Center(
child: circularProgress(),
),
)
: snapshot.data!.docs.length == 0
? //startBuildingCart()
Container()
: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
Items model = Items.fromJson(
snapshot.data!.docs[index].data()!
as Map<String, dynamic>,
);
if (index == 0) {
totalAmount = 0;
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
} else {
totalAmount = totalAmount +
(model.price! *
separateItemQuantityList![index]);
}
if (snapshot.data!.docs.length - 1 == index) {
WidgetsBinding.instance
.addPostFrameCallback((timeStamp) {
Provider.of<TotalAmount>(context,
listen: false)
.displayTotalAmount(
totalAmount.toDouble());
});
}
return CartItemDesign(
model: model,
context: context,
quanNumber: separateItemQuantityList![index],
);
},
childCount: snapshot.hasData
? snapshot.data!.docs.length
: 0,
),
);
},
),
],
),
);
}
}