I have the following FutureBuilder:
child: FutureBuilder(
future: fetchNotifications(widget.usuarioId),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<dynamic>? filteredList = snapshot.data as List;
return ListView.separated(
separatorBuilder: (BuildContext context, int index) =>
new Divider(
color: Colors.black26,
thickness: 0.5,
),
itemCount: filteredList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, index) {
NotificationModelo notificacion = filteredList[index];
var textoNot = notificacion.texto;
print("texto ${notificacion.texto}");
if (notificacion.texto == "New files available for you" &&
_fr) {
textoNot = "Nouveaux fichiers disponibles pour vous";
}
if (_fr) {}
return GestureDetector(
onTap: () {},
child: Container(
height: 50,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: GestureDetector(
onTap: () {
if (notificacion.categoria == "Travel Document") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BDTravelDocumentsNuevo()));
}
if (notificacion.categoria == "Itinerary") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BDItineraryNuevo()));
}
if (notificacion.categoria == "Experience") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BDExperiencesNuevo()));
}
if (notificacion.categoria == "News and Promos") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PrivateAreaNuevoDos()));
}
},
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Card(
elevation: 0,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: MediaQuery.of(context).size.width,
child: Center(
child: new Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
SizedBox(
width: 10,
),
notificacion.categoria ==
"Travel Document"
? CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage(
"assets/item2.png"),
backgroundColor:
Colors.transparent,
)
: notificacion.categoria ==
"Itinerary"
? CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage(
"assets/item3.png"),
backgroundColor:
Colors.transparent,
)
: notificacion.categoria ==
"Experience"
? CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage(
"assets/item4.png"),
backgroundColor:
Colors.transparent,
)
: CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage(
"assets/logolc.png"),
backgroundColor:
Colors.transparent,
),
SizedBox(
width: 15,
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Container(
width: 199,
height: 40,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"${textoNot}",
textAlign: TextAlign.start,
maxLines: 1,
overflow:
TextOverflow.ellipsis,
style: TextStyle(
fontSize: 15,
fontWeight:
FontWeight.bold),
),
],
),
),
],
),
Spacer(),
GestureDetector(
onTap: () {},
child: notificacion.categoria ==
"Push"
? Container()
: IconButton(
onPressed: () {
if (notificacion
.categoria ==
"Travel Document") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BDTravelDocumentsNuevo()));
}
if (notificacion
.categoria ==
"Itinerary") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BDItineraryNuevo()));
}
if (notificacion
.categoria ==
"Experience") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
BDExperiencesNuevo()));
}
if (notificacion
.categoria ==
"News and Promos") {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PrivateAreaNuevoDos()));
}
},
icon: Icon(
Icons.arrow_forward_ios,
)),
)
],
),
),
),
)),
),
),
),
);
},
);
}
return AnyNotification();
}),
It is working as it should, the only issue is that I need to show the list data just after loading the data is finished, and now during loading time it is showing the widget AnyNotification(), which I want to show only when there are any data to show.
My customer doesn´t want to show anything during loading time.
You can follow this structure.
return FutureBuilder(
future: future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("got error");
}
if (snapshot.hasData) {
List<dynamic>? filteredList = snapshot.data as List?;
if (filteredList == null || filteredList.isEmpty) {
return AnyNotification();
} else {
return ListView.separated(
itemBuilder: itemBuilder,
separatorBuilder: separatorBuilder,
itemCount: itemCount,
);
}
}
return Text("NA State");
},
);
Find more about FutureBuilder-class.
Try the following code:
FutureBuilder(
future: fetchNotifications(widget.usuarioId),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return const Text("Error");
}
if (snapshot.hasData) {
List<dynamic>? filteredList = snapshot.data as List;
return ListView.separated(
separatorBuilder: (BuildContext context, int index) => const Divider(color: Colors.black26,thickness: 0.5),
itemCount: filteredList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, index) {
NotificationModelo notificacion = filteredList[index];
var textoNot = notificacion.texto;
print("texto ${notificacion.texto}");
if (notificacion.texto == "New files available for you" && _fr) {
textoNot = "Nouveaux fichiers disponibles pour vous";
}
if (_fr) {}
return GestureDetector(
onTap: () {},
child: Container(
height: 50,
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: GestureDetector(
onTap: () {
if (notificacion.categoria == "Travel Document") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDTravelDocumentsNuevo()));
}
if (notificacion.categoria == "Itinerary") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDItineraryNuevo()));
}
if (notificacion.categoria == "Experience") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDExperiencesNuevo()));
}
if (notificacion.categoria == "News and Promos") {
Navigator.push(context, MaterialPageRoute(builder: (context) => PrivateAreaNuevoDos()));
}
},
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Card(
elevation: 0,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(width: 10),
notificacion.categoria == "Travel Document"
? const CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage("assets/item2.png"),
backgroundColor: Colors.transparent,
)
: notificacion.categoria == "Itinerary"
? const CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage("assets/item3.png"),
backgroundColor: Colors.transparent,
)
: notificacion.categoria == "Experience"
? const CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage("assets/item4.png"),
backgroundColor: Colors.transparent,
)
: const CircleAvatar(
radius: 20.0,
backgroundImage: AssetImage("assets/logolc.png"),
backgroundColor: Colors.transparent,
),
const SizedBox(width: 15),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 199,
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"$textoNot",
textAlign: TextAlign.start,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
],
),
),
],
),
const Spacer(),
GestureDetector(
onTap: () {},
child: notificacion.categoria == "Push"
? Container()
: IconButton(
onPressed: () {
if (notificacion.categoria == "Travel Document") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDTravelDocumentsNuevo()));
}
if (notificacion.categoria == "Itinerary") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDItineraryNuevo()));
}
if (notificacion.categoria == "Experience") {
Navigator.push(context, MaterialPageRoute(builder: (context) => BDExperiencesNuevo()));
}
if (notificacion.categoria == "News and Promos") {
Navigator.push(context, MaterialPageRoute(builder: (context) => PrivateAreaNuevoDos()));
}
},
icon: const Icon(
Icons.arrow_forward_ios,
),
),
),
],
),
),
),
),
),
),
),
),
);
},
);
}
return AnyNotification();
},
),
Related
We are running a Future which should be setting the initial/default at time of load but we cannot seem to get this to work. The default seems to update only state change
return FutureBuilder<List<Payment>>(
future: DatabaseService.getPayments(widget.user!.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
const Divider(),
ListView.separated(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return Dismissible(
direction: DismissDirection.endToStart,
key: Key(snapshot.data![index].cardId!),
onDismissed: (direction) {
// Remove the item from the data source.
setState(() {
snapshot.data!.removeAt(index);
});
},
// Show a red background as the item is swiped away.
background: Container(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
color: Colors.red,
alignment: Alignment.centerRight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.delete_forever_outlined,
color: Colors.white,
size: 32,
),
Text(
'Delete',
style: TextStyle(color: Colors.white),
),
],
),
),
confirmDismiss:
(DismissDirection dismissDirection) async {
switch (dismissDirection) {
case DismissDirection.endToStart:
case DismissDirection.startToEnd:
return await _showConfirmationDialog(
context,
'delete',
snapshot.data![index],
widget.user) ==
true;
case DismissDirection.horizontal:
case DismissDirection.vertical:
case DismissDirection.up:
case DismissDirection.down:
case DismissDirection.none:
break;
}
return false;
},
child: ListTile(
onTap: () {
setState(() {
paymentDefault = snapshot.data![index].cardId;
DatabaseService.createDefaultPayment(
context,
snapshot.data![index].cardId,
widget.user!.id);
});
},
leading: CircleAvatar(
backgroundColor:
snapshot.data![index].brand == 'MasterCard'
? Colors.amber[100]
: Colors.blue[100],
radius: 30,
child: loadImage(snapshot.data![index].brand)),
selected:
paymentDefault == snapshot.data![index].cardId,
title: Text('•••• ${snapshot.data![index].last4}'),
subtitle: Text(
'Exp. ${snapshot.data![index].expMonth}/${snapshot.data![0].expYear}'),
trailing:
paymentDefault == snapshot.data![index].cardId
? const Icon(Icons.check, color: Colors.green)
: const SizedBox.shrink(),
));
},
separatorBuilder: (context, index) {
return Divider(
height: 0,
color: Colors.grey[300],
);
}),
],
);
}
Use initialData prop in FutureBuilder
The data that will be used to create the snapshots provided until a non-null future has completed.
return FutureBuilder<List<Payment>>(
initialData: <Your initial Data here> 👈 Here
future: DatabaseService.getPayments(widget.user!.id),
builder: (context, snapshot) {
...
}
When I am changing the value of a dropdown, it does not display the new value.
I am using two documents.
One is containing only a String field.
In the second document, I have a lot of fields.
I have tried different options, but it is not working properly.
Below, you will find the code I am using, it will be easier to understand.
My project is stuck because I am not finding the solution. I will be late on planning if I do not solve this.
If someone can help, it will be highly appreciated. Thank you
Widget MyBody() {
return Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 1.4,
width: MediaQuery.of(context).size.width,
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('goals')
.orderBy('goal_Name', descending: false)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
QuerySnapshot data = snapshot.requireData;
return ListView.builder(
itemCount: data.size,
itemBuilder: (context, index) {
DocumentSnapshot document = snapshot.data.docs[index];
selectedFocus = document['area_of_focus_Name'] ;
String idFocus = document['area_of_focus_id'];
test.add(document['area_of_focus_Name']);
print(test);
return Wrap(
children: [
Container(
height: 210,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
40)),
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.blue, width: 3),
borderRadius: BorderRadius.all(
Radius.circular(45))
),
child: SwipeActionCell(
key: ObjectKey(document['goal_Name']),
trailingActions: <SwipeAction>[
SwipeAction(
title: "delete",
onTap: (
CompletionHandler handler) {
CollectionReference users = FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth.instance
.currentUser.uid)
.collection('goals');
users
.doc(document.id)
.delete()
.then((value) =>
print("Goal Deleted"))
.catchError((error) =>
print(
"Failed to delete Goal: $error"));
},
color: Colors.red),
],
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: ConstrainedBox(
constraints: BoxConstraints(
minWidth: leadingIconMinSize,
minHeight: leadingIconMinSize,
maxWidth: leadingIconMaxSize,
maxHeight: leadingIconMaxSize,
),
child: Padding(
padding: const EdgeInsets.only(
top: 16.0),
child: IconButton(
icon: Icon(Icons.edit),
onPressed: () {
//EDIT CONTEXT
//print (document['area_of_focus_Name']);
showDialog(
context: context,
barrierDismissible: true,
builder: (
BuildContext context) {
return AlertDialog(
title: Text("Edit Goal"),
content:
TextFormField(
initialValue: document['goal_Name'],
onChanged: (value) {
setState(() {_newGoalName = value;
});
},
),
actions: <Widget>[
TextButton(
child: Text("OK"),
onPressed: () {
setState(() {
var contextRecordID = (document.id);
FirebaseFirestore
.instance
.collection('Users')
.doc(
FirebaseAuth
.instance
.currentUser
.uid)
.collection('goals')
.doc(
contextRecordID)
.update(
{
'goal_Name': _newGoalName,
});
});
Navigator.of(context).pop(true);
},
),
//OK Button
TextButton(
child: Text(
"Cancel"),
onPressed: () {
Navigator.of(context).pop(false);
},
),
//Cancel Button
],
);
});
}
),
),),
// trailing: IconButton(icon: Icon(Icons.keyboard_arrow_right),),
title: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child:
Text(
//'goal_Name' correspond au nom du champ dans la table
document['goal_Name'],
style: TextStyle(fontSize: 20,
fontWeight: FontWeight.bold),
maxLines: 6,
overflow: TextOverflow.ellipsis,
),
)
],
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('area_of_Focus')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData)
const Text("Loading.....");
else {
List<DropdownMenuItem> focusItems = [];
for (int i = 0; i < snapshot.data.docs.length; i++) {
DocumentSnapshot snap = snapshot.data.docs[i];
focusItems.add(
DropdownMenuItem(
child: Text(
snap['area_of_Focus_Name'], //OK
style: TextStyle(color: Colors.black),
),
value: (snap['area_of_Focus_Name']),
),
);
}
return Row(
children:<Widget> [
DropdownButton(
items: focusItems,
onChanged: (focusValue) {
setState(() {
selectedFocus = focusValue;
});
},
value: selectedFocus,
isExpanded: false,
hint: SizedBox(
width:MediaQuery.of(context).size.width*0.6,
height: 40.0,
child: Text( document['area_of_focus_Name'],//taskAreaFocus,
style: TextStyle(color: Colors.black),// (0xff29B6F6)),
),
),
)]);
}
return Container(
height: 0,width: 0,
);
}),
),
/* MyApp()*/
],
),
),
),
),
),
),
]
);
});
}
}))
]);
}
after a few weeks of using Flutter CRUD I was running normally and able to enter the database, but this time I encountered an error as shown below.
The error appears when I finish editing data, delete data. What do you think the solution to this problem is, friends?
Here I provide a snippet of my source code
listnasabah.dart
class ListNasabah {
ApiService apiService;
ListNasabah({this.apiService});
void getNasabah() {
apiService.getNasabah().then((nasabah) {
print(nasabah);
});
}
Widget createViewList() {
return SafeArea(
child: FutureBuilder(
future: apiService.getNasabah(),
builder: (BuildContext context, AsyncSnapshot<List<Nasabah>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(
'Something wrong with message: ${snapshot.error.toString()}',
textAlign: TextAlign.center,
),
);
} else if (snapshot.connectionState == ConnectionState.done) {
List<Nasabah> nasabah = snapshot.data;
return nasabahListView(nasabah);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
Widget nasabahListView(List<Nasabah> listnasabah) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
Nasabah nasabah = listnasabah[index];
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
nasabah.nama_debitur,
style: Theme.of(context).textTheme.bodyText1,
),
Text(nasabah.alamat),
Text(nasabah.no_ktp),
Text(nasabah.no_telp),
Text(nasabah.no_selular),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
ElevatedButton.icon(
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () async {
apiService
.deleteNasabah(nasabah.id)
.then((value) => Navigator.of(
context)
.pushReplacement(
MaterialPageRoute(
builder: (context) =>
DataNasabah())));
})
],
),
);
},
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
icon: Icon(Icons.delete),
label: Text('Hapus'),
),
SizedBox(
width: 5,
),
ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailNasabah(
nasabah: nasabah,
),
),
);
},
icon: Icon(Icons.navigate_next),
label: Text(
'Detail',
),
)
],
)
],
),
),
),
);
},
itemCount: listnasabah.length,
),
);
}
}
I am trying to show two future builders with gridview in the column widget, but it is showing me one future builder of the department and not showing the other future builder when scrolling it. how to show the future builder of hot product? it will be helpful for me
import 'dart:convert';
import 'package:apipractice/Models/Category_model.dart';
import 'package:apipractice/Models/Department_model.dart';
import 'package:apipractice/Models/HotProduct_model.dart';
import 'package:apipractice/Screens/Department.dart';
import 'package:apipractice/Screens/cart.dart';
import 'package:apipractice/Screens/categorry.dart';
import 'package:apipractice/Screens/products.dart';
import 'package:apipractice/Screens/selected_Category.dart';
import 'package:apipractice/Screens/subCategory.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
Future<HotProductModel> getHotProducts() async {
var data = jsonDecode(response.body);
if (response.statusCode == 200) {
return HotProductModel.fromJson(data[0]);
} else {
throw Exception('Failed to load album');
}
}
List images = [
"assets/Image1.jpeg",
"assets/Image2.jpeg",
"assets/Image3.jpeg",
"assets/Image4.jpeg",
"assets/Image5.jpeg",
"assets/Image6.jpeg",
];
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
child: ListTile(
leading: CircleAvatar(
child: Image(image: AssetImage("images/user.png")),
radius: 25,
),
title: Text(
"Username",
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text("abcuser#gmail.com"),
),
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Show Product'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Products()),
);
},
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Show Category'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Categorry()),
);
},
),
ListTile(
leading: Icon(Icons.note),
title: const Text('Department'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Department()),
);
},
),
],
),
),
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 24, 119, 197),
title: Text("Dubai Super Store"),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => Cart()),
),
);
},
icon: Icon(Icons.shopping_cart))
],
),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: EdgeInsets.all(10),
height: 35,
width: double.infinity,
child: TextField(
decoration: InputDecoration(
hoverColor: Colors.blue,
prefixIconColor: Colors.blue,
labelText: "Search Product",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
),
Text(
"Note: Free Delivery Above Rs.2000",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.red.shade700,
fontSize: 17),
),
Container(
height: 200,
width: double.infinity,
child: CarouselSlider.builder(
itemCount: images.length,
options: CarouselOptions(
height: 400,
viewportFraction: 1,
autoPlay: true,
),
itemBuilder: (context, index, realindex) {
final urlImages = images[index];
return buildImage(urlImages, index);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Categorry()),
);
},
child: Image(
height: 70,
width: 70,
image: AssetImage("assets/Categories.jpeg"),
),
),
Text("Categories")
],
),
),
Container(
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SubCategory()),
);
},
child: Image(
height: 70,
width: 70,
image: AssetImage("assets/SubCategory.jpeg")),
),
Text("Sub Category")
],
),
)
],
),
SizedBox(height: 20),
Text(
"Department",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: Color.fromARGB(255, 16, 113, 192)),
),
FutureBuilder<DepartmentModel>(
future: getDepartment(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: snapshot.data!.sKUDepartmentDetail!.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
var fetchid =
"${snapshot.data!.sKUDepartmentDetail![index].sKUDeptId}";
fetchCategory = fetchid;
setState(() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SelectedCategory()),
);
});
},
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
),
elevation: 10.0,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
child: Stack(children: [
CachedNetworkImage(
imageUrl: snapshot
.data!
.sKUDepartmentDetail![index]
.imageUrl1!,
height: 150,
width: 200,
fit: BoxFit.fitWidth,
errorWidget: (context, url, error) {
return Image(
image: AssetImage(
"assets/placeholder.jpg"));
},
),
]),
),
Text(
snapshot
.data!.sKUDepartmentDetail![index].name!,
style: TextStyle(fontWeight: FontWeight.bold),
)
],
),
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
// SizedBox(height: 20),
Text(
"Hot Product",
style: TextStyle(fontSize: 20),
),
FutureBuilder<HotProductModel>(
future: getHotProducts(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data!.productDetail!.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 3,
offset: Offset(1.0, 1.0),
)
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CachedNetworkImage(
imageUrl: snapshot.data!.productDetail![index]
.sKUImageURL1!,
height:
MediaQuery.of(context).size.height * 0.12,
width: double.infinity,
fit: BoxFit.fitWidth,
errorWidget: (context, url, error) {
return Image(
image: AssetImage(
"assets/placeholder.jpg"));
},
),
SizedBox(
height: 10,
),
Text(
"${snapshot.data!.productDetail![index].sKUName!}"),
Text(
"Rs: ${snapshot.data!.productDetail![index].salePrice!}",
style: TextStyle(
color: Colors.blue,
fontSize: 20,
fontWeight: FontWeight.bold),
),
Text(
"Rs: ${snapshot.data!.productDetail![index].retailPrice!}",
style: TextStyle(
decoration: TextDecoration.lineThrough,
color: Colors.red),
),
ElevatedButton(
onPressed: () {
var product = snapshot
.data!.productDetail![index].sKUId;
if (cartList.contains(product)) {
print("already exist");
} else {
cartList.add({
"Id": snapshot
.data!.productDetail![index].sKUId
});
}
},
child: Text("Add to Cart"))
],
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return CircularProgressIndicator();
}
})
],
),
),
);
}
This is the output of the code
[![output image][1]][1]
The problem is solved it is only not showing because of screen navigation bar now its fine
I am getting the Error: Could not find the correct Provider above this MainScreenPage Widget. I cannot figure out what is wrong with my code since my MultiProvider is the parent of MaterialApp.
Things I tried which did not help:
Stopped debugging and started debugging.
Moved MultiProvider inside runApp, making MyApp its child.
I would very much appreciate it if anybody could help.
What shown on debug console
The relevant error-causing widget was
MainScreenPage lib/main.dart:22 (that is "widget = MainScreenPage();")
<main.dart>
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
User? firebaseUser = FirebaseAuth.instance.currentUser;
Widget widget;
if (firebaseUser != null) {
print(firebaseUser.email);
widget = MainScreenPage();
} else {
widget = LoginPage();
}
return MultiProvider(
providers: [
StreamProvider<User?>(
initialData: null,
create: (context) => FirebaseAuth.instance.authStateChanges(),
)
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'BookTracker',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: GoogleFonts.notoSansTextTheme(
Theme.of(context).textTheme,
),
),
home: widget,
),
);
}
}
<main_screen_page.dart>
class MainScreenPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
CollectionReference userCollectionReference =
FirebaseFirestore.instance.collection('users');
CollectionReference bookCollectionReference =
FirebaseFirestore.instance.collection('books');
List<Book> userBooksReadList = [];
// int booksRead = 0;
var authUser = Provider.of<User>(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white24,
elevation: 0,
toolbarHeight: 77,
centerTitle: false,
title: Row(
children: [
Text(
'A.Reader',
style: Theme.of(context).textTheme.headline6!.copyWith(
color: Colors.redAccent, fontWeight: FontWeight.bold),
),
],
),
actions: [
StreamBuilder<QuerySnapshot>(
stream: userCollectionReference.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
final userListStream = snapshot.data!.docs.map((user) {
return MUser.fromDocument(user);
}).where((user) {
return (user.uid == authUser.uid);
}).toList();
MUser curUser = userListStream[0];
return Column(
children: [
InkWell(
child: SizedBox(
height: 40,
width: 40,
child: CircleAvatar(
radius: 60,
backgroundImage: NetworkImage(curUser.avatarUrl ??
'https://picsum.photos/id/1022/300'),
backgroundColor: Colors.white,
child: Text(''),
),
),
onTap: () {
showDialog(
context: context,
builder: (context) {
return createProfileDialog(
context, curUser, userBooksReadList);
},
);
},
),
Text(
curUser.displayName.toUpperCase(),
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.black),
)
],
);
},
),
TextButton.icon(
onPressed: () {
FirebaseAuth.instance.signOut().then((value) {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
));
});
},
icon: Icon(Icons.logout),
label: Text(''),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BookSearchPage(),
));
},
child: Icon(
Icons.add,
),
backgroundColor: Colors.redAccent,
),
body: Column(
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.only(top: 12, left: 12, bottom: 10),
child: RichText(
text: TextSpan(
style: Theme.of(context).textTheme.headline6,
children: [
TextSpan(text: '今、'),
TextSpan(
text: '読んでいるのは',
style: TextStyle(fontWeight: FontWeight.w600)),
TextSpan(text: '…'),
]),
),
),
SizedBox(
height: 10,
),
StreamBuilder<QuerySnapshot>(
stream: bookCollectionReference.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('問題が発生しました (T.T)');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Expanded(
flex: 1,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.lime.shade300,
)));
}
if (snapshot.data!.docs.isEmpty) {
return Text('表示する書籍データがありません',
style: Theme.of(context).textTheme.headline4);
}
final userBookFilteredReadListStream =
snapshot.data!.docs.map((book) {
return Book.fromDocument(book);
}).where((book) {
return ((book.userId == authUser.uid)) &&
(book.finishedReading == null) &&
(book.startedReading != null);
}).toList();
userBooksReadList = snapshot.data!.docs.map((book) {
return Book.fromDocument(book);
}).where((book) {
return ((book.userId == authUser.uid)) &&
(book.finishedReading != null) &&
(book.startedReading != null);
}).toList();
return Expanded(
flex: 1,
child: (userBookFilteredReadListStream.length > 0)
? ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: userBookFilteredReadListStream.length,
itemBuilder: (context, index) {
Book book = userBookFilteredReadListStream[index];
return InkWell(
child: ReadingListCard(
buttonText: '読書中',
image: book.photoUrl!,
title: book.title,
author: book.author!,
rating: (book.rating) != null ? book.rating : 0,
),
onTap: () {
showDialog(
context: context,
builder: (context) {
return BookDetailDialog(
book: book,
);
},
);
},
);
},
)
: Text('読書中の本はありません (・o・)',
style: Theme.of(context).textTheme.headline6));
},
),
Container(
width: double.infinity,
margin: EdgeInsets.only(left: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(children: [
TextSpan(
text: '読みたい本リスト',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
color: kBlackColor),
),
]),
),
],
),
),
SizedBox(
height: 8,
),
StreamBuilder<QuerySnapshot>(
stream: bookCollectionReference.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('問題が発生しました (T.T)');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Expanded(
flex: 1,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.lime.shade300,
)));
}
if (snapshot.data!.docs.isEmpty) {
return Center(
child: Text('表示する書籍データがありません',
style: Theme.of(context).textTheme.headline4),
);
}
final readingListListBook = snapshot.data!.docs.map((book) {
return Book.fromDocument(book);
// ログイン中ユーザのuidでbookをフィルタリングする
}).where((book) {
return ((book.userId == authUser.uid)) &&
(book.startedReading == null) &&
(book.finishedReading == null);
}).toList();
return Expanded(
flex: 1,
child: (readingListListBook.length > 0)
? ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: readingListListBook.length,
itemBuilder: (context, index) {
Book book = readingListListBook[index];
return InkWell(
child: ReadingListCard(
buttonText: '未読',
rating: (book.rating) != null ? book.rating : 0,
image: book.photoUrl!,
title: book.title,
author: book.author!,
isBookRead: false,
),
onTap: () {
showDialog(
context: context,
builder: (context) {
return BookDetailDialog(
book: book,
);
},
);
},
);
},
)
: Text('表示する書籍データがありません ^_^;',
style: Theme.of(context).textTheme.headline6));
},
),
],
),
);
}
}
"var authUser = Provider.of<User>(context);" could you add a question mark to this syntax? It should look like this: "var authUser = Provider.of<User?>(context);"