Future not setting default value on load - flutter

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) {
...
}

Related

Showing empty widget while FutureBuilder is loading data

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();
},
),

how can I use flutter slidable let only one item move??not working key

I use flutter_slidable: ^0.6.0.
I hope working only one item slidable in my listview.
if one item slide by user, all the others(whatever open or close) r closed.
some docs say use key.but mine is not working.
return ListView.builder(
physics: ClampingScrollPhysics(),
itemCount: snapshot.data!.size,
shrinkWrap: true,
itemBuilder: (BuildContext context, count) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Slidable(
key: Key(snapshot.data!.docs[count].id),
controller: slidableController,
actionPane: SlidableDrawerActionPane(),
actionExtentRatio: 0.25,
actions: <Widget>[
widget.pin == 0
? IconSlideAction(
caption: 'pin 제거',
color: Colors.black45,
icon: Icons.push_pin_rounded,
onTap: () {
pinEraseRoom(widget.roomId);
},
)
: IconSlideAction(
caption: 'Pin',
color: Colors.black45,
icon: Icons.push_pin_outlined,
onTap: () {
pinRoom(widget.roomId);
},
),
],
secondaryActions: <Widget>[
IconSlideAction(
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
onTap: () {
deleteRoom(widget.roomId);
},
),
],
mine
https://i.stack.imgur.com/eFW7J.jpg
resolved
/// parent
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(other)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container();
}
return ConversationList(
controller: slidableController,
//////// child widget in coversationList widget
itemBuilder: (BuildContext context, count) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Slidable(
key: Key(snapshot.data!.docs[count].id),
controller: widget.controller,
actionPane: SlidableDrawerActionPane(),
actionExtentRatio: 0.25,
actions: <Widget>[
widget.pin == 0
//
More clarity can be found here

Flutter Gridview Builder lag when coming back to the screen

I have a gridview.builder that fetches images from an API, images are already compressed to a max of 70kb each. I am also using pagination usin to fetch more data. When the grid crosses 30+ images the scrolling becomes choppy and when I go to a page by clicking on any image and then I come back many images load again everything again. I am maintaining the state using IndexedStack. And back animation is also stuttering. What am I doing wrong here?
Gridview Builder Code:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: postsList.posts.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 3,
mainAxisSpacing: 3,
),
itemBuilder: (context, index) {
return ProfilePostImageCard(
length: postsList.posts.length,
post: postsList.posts[index],
stringOfPostID: stringOfPostID,
);
})
ProfilePostImageCard
class ProfilePostImageCard extends StatelessWidget {
final ProfilePostModel post;
final String stringOfPostID;
final int length;
ProfilePostImageCard({Key key, this.post, this.stringOfPostID, this.length}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfileFeedsPage(
currentMemberImage: CurrentUser().currentUser.image,
listOfPostID: stringOfPostID,
postID: post.postId,
logo: CurrentUser().currentUser.logo,
country: CurrentUser().currentUser.country,
memberID: CurrentUser().currentUser.memberID,
)));
},
child: Container(
child: Stack(
children: [
AspectRatio(
aspectRatio: 1,
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: post.postAllImage,
),
),
post.dataMultiImage == 1
? Positioned.fill(
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/multiple.png",
height: 2.5.h,
),
)),
)
: Container(),
post.postType == "Video" || post.postType == "svideo"
? Positioned.fill(
child: Align(
alignment: Alignment.topRight,
child: Padding(
padding: EdgeInsets.all(6.0),
child: Icon(
Icons.video_collection,
color: Colors.white,
size: 2.5.h,
))),
)
: Container(),
],
),
),
);
}
}
Full Code
SmartRefresher(
enablePullDown: true,
enablePullUp: selectedIndex == 1 ? false : true,
header: CustomHeader(
builder: (context, mode) {
return Container(
child: Center(child: loadingAnimation()),
);
},
),
footer: CustomFooter(
builder: (BuildContext context, LoadStatus mode) {
Widget body;
if (mode == LoadStatus.idle) {
body = Text("");
} else if (mode == LoadStatus.loading) {
body = loadingAnimation();
} else if (mode == LoadStatus.failed) {
body = Container(
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: new Border.all(color: Colors.black, width: 0.7),
),
child: Padding(
padding: EdgeInsets.all(12.0),
child: Icon(CustomIcons.reload),
));
} else if (mode == LoadStatus.canLoading) {
body = Text("");
} else {
body = Text("No more Data");
}
return Container(
height: 55.0,
child: Center(child: body),
);
},
),
controller: _postRefreshController,
onRefresh: _onRefresh,
onLoading: () {
if (selectedIndex == 0) {
_onLoading();
} else {
print("blog");
}
},
child: ListView(
physics: AlwaysScrollableScrollPhysics(),
children: [
profileLoaded == true
? ProfileCard(
userImage: userImage,
totalPosts: totalPosts,
followers: followers,
following: following,
bio: bio,
name: name,
shortcode: shortcode,
list: list,
)
: Container(),
TabBar(
indicatorColor: Colors.black,
tabs: <Tab>[
Tab(
child: Text(
"Posts",
style: blackBold.copyWith(color: Colors.black, fontSize: 10.0.sp),
),
),
Tab(
child: Text(
"Blogs",
style: blackBold.copyWith(color: Colors.black, fontSize: 10.0.sp),
),
),
Tab(
child: Text(
"Channel",
style: blackBold.copyWith(color: Colors.black, fontSize: 10.0.sp),
),
),
],
controller: _tabController,
onTap: (int index) {
setState(() {
selectedIndex = index;
_tabController.animateTo(index);
});
},
),
IndexedStack(
children: <Widget>[
GestureDetector(
onHorizontalDragUpdate: (details) {
if (details.delta.dx < 0) {
setState(() {
_tabController.animateTo(1);
selectedIndex = 1;
});
} else if (details.delta.dx > 0) {
setState(() {
_tabController.animateTo(2);
selectedIndex = 2;
});
}
},
child: Visibility(
child: Container(
child: hasPosts == true
? GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: postsList.posts.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 3,
mainAxisSpacing: 3,
),
itemBuilder: (context, index) {
return ProfilePostImageCard(
length: postsList.posts.length,
post: postsList.posts[index],
stringOfPostID: stringOfPostID,
);
})
: Container(),
),
maintainState: true,
visible: selectedIndex == 0,
),
),
GestureDetector(
onHorizontalDragUpdate: (details) {
if (details.delta.dx < 0) {
setState(() {
_tabController.animateTo(2);
selectedIndex = 2;
});
} else if (details.delta.dx > 0) {
setState(() {
_tabController.animateTo(0);
selectedIndex = 0;
});
}
},
child: Visibility(
child: Container(
child: hasPosts == true
? Column(
children: [
ListView.builder(
controller: widget.scrollController,
shrinkWrap: true,
//physics: NeverScrollableScrollPhysics(),
itemCount: blogsList.blogs.length,
itemBuilder: (context, index) {
var blog = blogsList.blogs[index];
return PersonalBlogCard(
blog: blog,
index: index,
lastIndex: blogsList.blogs.length - 1,
);
},
),
Padding(
padding: EdgeInsets.symmetric(vertical: 2.0.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
if (currentPage > 1) {
setState(() {
hasBlogs = false;
currentPage = --currentPage;
});
getBlogs();
}
},
child: CircleAvatar(
radius: 3.0.h,
backgroundColor: primaryBlueColor,
child: Icon(
Icons.arrow_back_ios_outlined,
color: Colors.white,
)),
),
Text(
"Page " + currentPage.toString() + "/" + totalPages.toString(),
style: TextStyle(fontSize: 11.0.sp),
),
GestureDetector(
onTap: () {
if (currentPage < totalPages) {
setState(() {
hasBlogs = false;
currentPage = ++currentPage;
});
getBlogs();
}
},
child: CircleAvatar(
radius: 3.0.h,
backgroundColor: primaryBlueColor,
child: Icon(
Icons.arrow_forward_ios_outlined,
color: Colors.white,
)),
)
],
),
)
],
)
: Container(),
),
maintainState: true,
visible: selectedIndex == 1,
),
),
GestureDetector(
onHorizontalDragUpdate: (details) {
if (details.delta.dx < 0) {
setState(() {
_tabController.animateTo(0);
selectedIndex = 0;
});
} else if (details.delta.dx > 0) {
setState(() {
_tabController.animateTo(1);
selectedIndex = 1;
});
}
},
child: Visibility(
child: Container(
child: hasPosts == true
? StaggeredGridView.countBuilder(
addAutomaticKeepAlives: true,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
crossAxisCount: 3,
itemCount: postsList.posts.length,
mainAxisSpacing: 3,
crossAxisSpacing: 3,
itemBuilder: (context, index) {
return ProfilePostImageCard(
length: postsList.posts.length,
post: postsList.posts[index],
stringOfPostID: stringOfPostID,
);
},
staggeredTileBuilder: (index) {
return StaggeredTile.fit(1);
},
)
: Container(),
),
maintainState: true,
visible: selectedIndex == 2,
),
),
],
index: selectedIndex,
),
],
),
)
This is the solution. Evict the image from cache on dispose method and no more lag on screen transition.
class ProfilePostImageCard extends StatefulWidget {
const ProfilePostImageCard({Key key, this.url}) : super(key: key);
#override
State createState() => new _ProfilePostImageCardState();
}
class _ProfilePostImageCardState extends State<ProfilePostImageCard> {
#override
void dispose() {
// needs to match the url and scale from below
CachedNetworkImage.evictFromCache(widget.url);
}
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: post.postAllImage,
),
),;
}
}

Flutter close a dialog and reload page with filtered list of the condition selected

import 'package:flutter_event_app/constant/color.dart';
import 'package:flutter_event_app/network/models/categories.dart';
import 'package:flutter_event_app/network/models/event_model.dart';
import 'package:flutter_event_app/network/models/time.dart';
import 'package:flutter_event_app/network/services/event_api.dart';
import 'package:flutter_event_app/pages/event_detail_page.dart';
import 'package:flutter_event_app/pages/search/home_search.dart';
import 'package:flutter_event_app/widgets/event_card.dart';
import 'package:flutter_event_app/widgets/no_events.dart';
import 'package:flutter_event_app/widgets/onload.dart';
class SelectedCategory extends StatefulWidget {
// SelectedCategory(Categories categories);
final Categories categories;
final Time time;
SelectedCategory(this.categories, [this.time]);
#override
_SelectedCategoryState createState() => _SelectedCategoryState();
}
class _SelectedCategoryState extends State<SelectedCategory> {
Categories categories;
Time timing;
String timeselect;
// Event event;
void viewEventDetail(Events event) {
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 300),
pageBuilder: (BuildContext context, animation, __) {
return FadeTransition(
opacity: animation,
child: EventDetailPage(event),
);
},
),
);
}
bool isLoading = false;
List<Events> upcomingEvents;
List categorizedupcomingEvents = [];
List categorizedPaidupcomingEvents = [];
List categorizedFreeupcomingEvents = [];
#override
void initState() {
_fetchData();
categories = widget.categories;
timing = widget.time;
// print(timing.id);
super.initState();
}
Future _fetchData() async {
setState(() => isLoading = true);
upcomingEvents = await getEventss();
categorizedupcomingEvents = upcomingEvents
.where((category) => category.category == categories.id)
.toList();
categorizedPaidupcomingEvents = categorizedupcomingEvents
.where((paid) => paid.is_paid == true)
.toList();
categorizedFreeupcomingEvents = categorizedupcomingEvents
.where((free) => free.is_paid == false)
.toList();
setState(() => isLoading = false);
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(
MediaQuery.of(context).size.height / 9.5,
),
child: AppBar(
title: Text(categories.categoryName),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.sort,
),
onPressed: () {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
showFilterByTimeDialog(context);
// )
// );
}),
IconButton(
icon: Icon(
Icons.more_vert,
),
onPressed: () {})
],
bottom: TabBar(
tabs: [
Text('All'),
Text('Paid'),
Text('Free'),
],
),
),
),
body: TabBarView(
children: <Widget>[
// All
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount: categorizedupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Paid
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedPaidupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedPaidupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedPaidupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
// Free
isLoading
? OnloadingCards()
: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: categorizedFreeupcomingEvents.isEmpty
? NoItems()
: ListView.builder(
itemCount:
categorizedFreeupcomingEvents.length,
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
// scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final event =
categorizedFreeupcomingEvents[index];
return EventCard(event,
onTap: () => viewEventDetail(event));
},
),
),
),
],
),
],
),
));
}
void showFilterByTimeDialog(BuildContext context) {
Dialog fancyDialog = Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: SingleChildScrollView(
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.5,
// alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
// color: Colors.greenAccent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
),
),
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.05,
child: Text(
"Time",
style: TextStyle(
color: Colors.deepPurple,
fontSize: 20,
fontWeight: FontWeight.w600),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
// color: Colors.red,
width: double.infinity,
child: ListView.builder(
shrinkWrap: true,
primary: false,
physics: BouncingScrollPhysics(),
itemCount: times.length,
itemBuilder: (context, int index) {
Time time = times[index];
return RaisedButton(
onPressed: () {
debugPrint('I am Awesome');
},
textColor: Colors.red,
// color: Colors.blueAccent,
disabledColor: Colors.grey,
disabledTextColor: Colors.white,
highlightColor: Colors.orangeAccent,
child: Text(time.name),
);
}),
),
),
),
],
),
),
),
);
showDialog(
context: context, builder: (BuildContext context) => fancyDialog);
}
}
Within the same page I have a dialog box as shown below
On the method showFilterByTimeDialog where I select an item and have to go back to the same page below the dialogue .Am still learning flutter and my issue is I need help when I select an item from the dialogue box,i refresh the same page and display a new filtered lst from the current list displayed on that page with a condition of the item selected from the dialogue box.

Flutter Firebase: not able update Database

I want to update my Collection with an NumberPicker in a Alert Dialog. I do not get any errors in code or from the emulator. When i press the button to update the code the terminal do not give any errors. Everything looks fine but for some reason i do not work. When you need more Information just leave a comment with what you excactly need. :)
import 'package:flutter/material.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:testapp/services/Services.dart';
import 'models/Goals.dart';
class Statistics extends StatefulWidget {
#override
_StatisticsState createState() => _StatisticsState();
}
class _StatisticsState extends State<Statistics> {
int _currentFirstValue = 1;
int totalFirst;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 260,
child: StreamBuilder(
stream: FirestoreService().getGoals(),
builder: (context, AsyncSnapshot<List<Goal>> snapshot) {
if (snapshot.hasError || !snapshot.hasData) {
return Center(child: CircularProgressIndicator(
backgroundColor: Color(0XFF1954A1),
));
}
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
// ignore: missing_return
Goal goal = snapshot.data[index];
return Row(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
height: 230,
width: 350,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Colors.grey[300],
offset: const Offset(0.5, 1),
blurRadius: 4.0,
spreadRadius: 0.1,
),
]),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('WeekGoals', style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w500,
),),
SizedBox(width: 100),
SizedBox(
height: 20,
width: 87,
child: FlatButton(
child: Text('edit', style: TextStyle(
fontSize: 17,
color: Colors.yellow[700]
),),
onPressed: () {
return showDialog(
context: context,
barrierDismissible: true,
builder: (context) => AlertDialog(
content: Column(
children: <Widget>[
Text('weekly goals'),
NumberPicker.integer(
initialValue: _currentFirstValue,
minValue: 1,
maxValue: 100,
onChanged: (newGoal) => setState(() => {
_currentFirstValue = newGoal,
totalFirst = _currentFirstValue,
})
),
Row(
children: <Widget>[
RaisedButton(
child: Text('edit goals'),
onPressed: () async {
Goal goal = Goal(
weekActivityGoal: totalFirst,
);
await FirestoreService().updateGoal(goal);
Navigator.pop(context, false);
},
),
FlatButton(
child: Text('Close'),
onPressed: () {
Navigator.pop(context, false);
},
)
],
)
],
),
)
);
},
),
)
],
),
SizedBox(height: 10),
Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 17.5),
child: CircularPercentIndicator(
header: Text('activitys', style: TextStyle(
fontSize: 17,
),),
radius: 130,
progressColor: Colors.red,
lineWidth: 8,
backgroundColor: Colors.grey[200],
percent: goal.weekActivity*100/goal.weekActivityGoal,
center: Text('${goal.weekActivity}/${goal.weekActivityGoal}'),
),
),
],
),
],
),
),
],
);
});
}),
),
);
}
}
Here this has been helping a lot of people try i out might help you too.
StreamBuilder(
stream: Firestore.instance.collection('Hearings').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Select lot');
case ConnectionState.waiting:
return Text('Awaiting bids...');
case ConnectionState.active:
{
print('active');
return Text('${snapshot.data}');
}
case ConnectionState.done:
{
print('Done');
return _buildList(context, snapshot.data);
}
}
return null;
}),
));
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return ListView(
padding: const EdgeInsets.only(top: 20.0),
children: snapshot.map((data) => _buildListItem(context, data)).toList(),
);
}
Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
final record = Record.fromSnapshot(data);
return Padding(
key: ValueKey(record.name),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5.0),
),
child: ListTile(
title: Text(record.name),
trailing: Text(record.votes.toString()),
onTap: () => Firestore.instance.runTransaction((transaction) async {
final freshSnapshot = await transaction.get(record.reference);
final fresh = Record.fromSnapshot(freshSnapshot);
await transaction
.update(record.reference, {'votes': fresh.votes + 1});
}),
),
),
);
}
}
class Record {
final String name;
final int votes;
final DocumentReference reference;
Record.fromMap(Map<String, dynamic> map, {this.reference})
: assert(map['name'] != null),
assert(map['votes'] != null),
name = map['name'],
votes = map['votes'];
Record.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
#override
String toString() => "Record<$name:$votes>";
}
This is where the link this info came from.