How can I change a container color on tap with Provider? - flutter

I am trying to create a custom style checkbox that is a container with rounded edges. It should show a different color icon when tapped. I am not sure how to do this can anyone help? Here is the code: (Edit I updated the code to show the gridview builder that the checkbox is placed in. The gridviewbuilder builds a card based on the length of a list in the provider class. I am trying to get the checkbox to work independently of the other gridview cards.
//this is the function in the provider class
toggleCheckbox(bool checkboxStatus){
if (checkboxStatus = false){
return checkboxStatus = true;
} else if (checkboxStatus = true){
return checkboxStatus = false;
}
notifyListeners();
}
GridView.builder(
itemCount: bloc.readingList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 12/16, crossAxisCount: 2, crossAxisSpacing: 20.0, mainAxisSpacing: 20),
itemBuilder: (BuildContext context, int index) {
return ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(3.0, 6.0),
blurRadius: 10.0)
],
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: NetworkImage('${bloc.readingList[index].storyImage}'),
fit: BoxFit.cover,
),
),
child: Padding(
padding: const EdgeInsets.only(
top: 8.0, bottom: 0.0, left: 0.0, right: 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TopicTag(index: index,),
CardContents(),
],
),
),
),
);
},
),
class CardContents extends StatefulWidget {
const CardContents({
Key key,
}) : super(key: key);
#override
_CardContentsState createState() => _CardContentsState();
}
class _CardContentsState extends State<CardContents> {
bool checkboxStatus = false;
#override
Widget build(BuildContext context) {
final bloc = Provider.of<ReadingListBloc>(context);
return ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Container(
color: Colors.blueGrey.withOpacity(.5),
child: Column(
children: <Widget>[
Text('Title Here (color change with topic)',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontFamily: "Calibre-Semibold",
letterSpacing: 1.0,
)),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 8.0, bottom: 8),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white),
child: GestureDetector(
onTap:(){},
// bloc.toggleCheckbox(checkboxStatus),
child: checkboxStatus
? Icon(Icons.check_circle, color: Colors.green)
: Icon(Icons.check_circle, color: Colors.white)),
),
),
],
),
],
),
),
),
);
}
}

Considering that you have setup your provider correctly, you could do something like below.
// add the property below to your provider
bool checkboxStatus = false;
void toggleCheckbox(){
checkboxStatus = !checkboxStatus;
notifyListeners();
}
Now for the listeners, you can just check this new property, considering that bloc is your provider.
GestureDetector(
onTap: () {
bloc.toggleCheckbox(checkboxStatus);
},
child: bloc.checkboxStatus ? Icon(Icons.check_box, color: Colors.green)
: Icon(Icons.check_circle, color: Colors.white)),
I'm assuming that for some reason you want to use a provider. Of course you could also use a StatefulWidget if you only need the status in this widget.

Related

How to draw line between 1 widget to 2nd widget Flutter

I'm trying to create a comment tree but I don't have any idea how to do that. The package I found on pub.dev is not like what I want. I mesh with codes. No tutorial found related to me.
This is what I want :
I want a tutorial or idea to create design like showing in the image.
You can draw line like this
SizeBox(
height : 2,
width : MediaQuery.of(context).size.width,
child : Container(color:Colors.black)
),
try this
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(width: 2.0, color:Colors.black),//(or use VerticalDivider())
SizedBox(width: 4.0),
YourCommentWidget(),
],
))
In your tree, you can use divider() for clear line, also you can use sizedbox.
firstwidget (
child : secondwidget (child : ..............)
)
simply you can wrap second widget with a padding.
Check this package. https://pub.dev/packages/flutter_fancy_tree_view
#Pradip said in comments.
If that you want, just add in pubspec.yaml file or you want to customize like in image just Copy the code from git repository and paste in your project as separate directory.
Edit as you want.
Finally, I achieve what I want. I think is not an Optimize way. I really like to know your comment on my code. It's litter meshy but the output looks nice.
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class TestTree extends StatelessWidget {
const TestTree({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('title'),
),
body: ListView(
children: [
commentTreeRoot(
context: context,
image:
'https://www.whatsappprofiledpimages.com/wp-content/uploads/2018/07/beaJKHutiful-girl-profile-p-199x300.jpg',
name: 'User Name',
subtitle: '11111 Comment Text User name Comment Text User name ',
posteDate: Text('20:18'),
content:
Text("""The :expressions will be suitable for girls, guys,\n
married people too. Because in life complications start and\n
ends with girls at the same time happiness comes to girls and only girls. Thus, even a silly waste paper will look bright when it is in the hands of beautiful girls.
The pixels are picture perfect in our website."""),
comments: [
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU,',
[
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU',
[],
margin: 40,
last: true)
]),
commentTreeChild(
context,
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT16eO5W8VPjVFrkvG8n_2FQKjByMcbLtBF4A&usqp=CAU',
last: true,
[]),
],
)
],
));
}
Widget commentTreeRoot({
required BuildContext context,
required String image,
required String name,
required String subtitle,
required Widget posteDate,
required Widget content,
required List<Widget> comments,
}) {
return Column(
children: [
CustomPaint(
painter: CreateLine(root: true),
child: Column(
// root
children: [
ListTile(
horizontalTitleGap: 0,
leading: CircleAvatar(
backgroundImage: NetworkImage(image),
),
title: Padding(
padding: const EdgeInsets.only(top: 15, left: 8),
child: Text(name),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 0, left: 8),
child: Text(
subtitle,
overflow: TextOverflow.clip,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
trailing: posteDate,
),
Container(
// Content
margin: EdgeInsets.only(left: 60),
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color.fromARGB(255, 240, 240, 240),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: content,
),
Column(
children: comments,
),
SizedBox(
height: 10,
),
commentRootTextfield(context),
],
),
)
],
);
}
Widget commentTreeChild(
BuildContext context, String image, List<Widget> commentReply,
{bool last = false, double margin = 60}) {
return Container(
margin: EdgeInsets.only(left: margin, top: 15),
child: CustomPaint(
painter: CreateLine(root: false, last: last),
child: Column(
// child 1
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 15,
backgroundImage: NetworkImage(image),
),
Expanded(
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Color.fromARGB(255, 240, 240, 240),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Column(
children: [
Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 8),
child: Text(
'User Name',
overflow: TextOverflow.ellipsis,
),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8),
child: Text('20:18'),
)
],
),
Text(
"""The expressions will be suitable for girls, guys,
"""),
],
),
),
),
],
),
),
last ? commnetChildTextField(context) : commnetChildReplyButton(),
Column(
children: commentReply,
)
],
), // child root
),
);
}
Widget commnetChildReplyButton() {
return Container(
margin: const EdgeInsets.only(
left: 30,
),
alignment: Alignment.centerLeft,
child: SizedBox(
height: 20,
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () {},
child: Text('Replay')),
));
}
Widget commnetChildTextField(BuildContext context) {
return FittedBox(
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 8, top: 16),
child: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
'https://img.etimg.com/thumb/msid-69381991,width-650,imgsize-594328,,resizemode-4,quality-100/hacker-1.jpg'),
radius: 15,
),
SizedBox(
width: 10,
),
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Color.fromARGB(255, 231, 231, 231),
border: Border.all(width: 0.5),
borderRadius: BorderRadius.all(Radius.circular(30))),
child: TextField(
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
hintText: 'Type your message...',
contentPadding:
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
isDense: true,
border: InputBorder.none,
),
style: TextStyle(color: Colors.white, fontSize: 20),
),
)
],
),
),
);
}
Widget commentRootTextfield(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 3, color: Color.fromARGB(255, 231, 231, 231)),
bottom:
BorderSide(width: 2, color: Color.fromARGB(255, 231, 231, 231)),
),
),
child: FittedBox(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
IconButton(onPressed: () {}, icon: Icon(FontAwesomeIcons.smile)),
SizedBox(
width: MediaQuery.of(context).size.width,
child: Container(
decoration: BoxDecoration(
color: Color.fromARGB(255, 231, 231, 231),
borderRadius: BorderRadius.all(Radius.circular(30))),
child: TextField(
minLines: 1,
maxLines: 3,
decoration: InputDecoration(
hintText: 'Type your message...',
contentPadding:
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
isDense: true,
border: InputBorder.none,
),
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
SizedBox(
width: 30,
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.attach_file,
size: 25,
))),
SizedBox(
width: 40,
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.mic,
size: 30,
)),
),
],
),
),
);
}
}
class CreateLine extends CustomPainter {
CreateLine({required this.root, this.last = false});
final bool root;
final bool last;
#override
void paint(Canvas canvas, Size size) {
final p1 = size.topLeft(root ? Offset(35, 65) : Offset(15, 40));
final p2 = root
? Offset(35, size.height - 53)
: Offset(15, size.height - (last ? 40 : 0));
final paint = Paint()
..color = Colors.black
..strokeWidth = 1;
canvas.drawLine(p1, p2, paint);
// TODO: implement paint
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
Output look like this now

how to make widget scale up when it selected in Flutter

I have an app that has pageView.builder and it contains 5 stack widget
how can I scale up the widget that user-selected, for example:
if the user scrolls to widget 3, widgets 1 & 2 become smaller than widget 3, and the same if he scrolls to widget 5 or 2
( the middle will become bigger than the widget on both sides)
my code :
Widget build(BuildContext context) {
// ignore: sized_box_for_whitespace
return Container(
height: 320,
child: PageView.builder(
controller: pageController,
itemCount: 5,
itemBuilder: (context, position) {
return _bulidPageItem(position);
}),
);
}
Widget _bulidPageItem(int index) {
//------------------------------------------------------------------------------
// Slide image 🚩
return Stack(
alignment: Alignment.topCenter,
children: [
Container(
margin: const EdgeInsets.only(left: 5, right: 5),
height: 220,
width: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: index.isEven
? const Color(0xFFffd28d)
: const Color(0xFF89dad0),
image: const DecorationImage(
image: AssetImage('images/chineseFood.jpg'), fit: BoxFit.cover),
),
),
//------------------------------------------------------------------------------
// Slide Information 🚩
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.only(left: 30, right: 30, bottom: 15),
height: 130,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
blurRadius: 6,
spreadRadius: 0.7,
offset: const Offset(1, 4))
],
borderRadius: BorderRadius.circular(25),
color: Colors.white,
),
//------------------------------------------------
// Slider title
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const BigText(
text: 'Chinese side',
),
//----------------------------------------------
// Slider Rating
const SizedBox(height: 10),
Row(
children: [
Wrap(
children: List.generate(
5,
(index) => const Icon(Icons.star,
color: AppColor.mainColor, size: 12),
),
),
const SizedBox(width: 10),
SmallText(text: 4.5.toString()),
const SizedBox(width: 10),
const SmallText(text: '1287 comments'),
],
),
const SizedBox(height: 20),
//----------------------------------------------
// Slider Icons
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const [
SliderIcons(
color: AppColor.iconColor1,
text: 'Normal',
icon: Icons.circle),
SliderIcons(
color: AppColor.mainColor,
text: '1.7km',
icon: Icons.location_pin),
SliderIcons(
color: AppColor.iconColor2,
text: '32min',
icon: FontAwesomeIcons.clock),
],
),
],
),
),
),
),
],
);
}
}
I think the carousel slider package provides the functionality you need. The package has an example, which exactly describes your issue.
you should try out https://api.flutter.dev/flutter/widgets/ListWheelScrollView-class.html
and for your layout, you can use rotate widget for the horizontal view and of course
you to use rotate widget on the child of the list too.
Save the current page and adjust the content based on that. Like below the current page, _currentPage == index, has smaller margins.
final _pageController = PageController(viewportFraction: 0.8);
int _currentPage = 0;
...
PageView.builder(
controller: _pageController,
itemCount: 5,
itemBuilder: (_, index) =>
Container(
margin: _currentPage == index
? const EdgeInsets.symmetric(vertical: 16)
: const EdgeInsets.symmetric(vertical: 64),
child: Image.network(
'https://picsum.photos/1080/1920?index=$index',
fit: BoxFit.cover,
loadingBuilder: (_, child, loadingProgress) {
if (loadingProgress == null) return child;
return const Center(child: CircularProgressIndicator());
}
)
),
onPageChanged: (page){
setState(() {
_currentPage = page;
});
},
)
)

List Tiles out of container when scrolling

I have a ListViewBuilder inside a container in my UI when I scroll the list tiles get out of the container like so :
This my code :
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: Container(
margin: const EdgeInsets.only(
left: 30, right: 30, bottom: 20),
width: getProportionateScreenWidth(600),
height: getProportionateScreenHeight(300),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(17),
topRight: Radius.circular(17),
bottomLeft: Radius.circular(17),
bottomRight: Radius.circular(17)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: ListView.builder(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: snapshot.data!.perimeters.length,
itemBuilder: (context,index){
return PerimListTile(
perimID: snapshot.data!.perimeters[index].perimeterId.toString(),
perimLabel: snapshot.data!.perimeters[index].label,
);
})),
],
),
),
)
I want the list tiles to stay inside the container even while scrolling , if anyone knows how to solve the issue I'd be grateful , thank you in advance.
Problem
I do not know the details about getProportionateScreenHeight you used but I assume that it returns a double value.
The ListView inside the Column is constrained by the height of the container through that.
Solution
Remove the height of the container and try mainAxisSize: MainAxisSize.min on Column.
Solve
[1] Use the clip behavior parameter in container Widget. And set it to hardEdge
clipBehavior: Clip.hardEdge,
[2] Wrap the ListTile Widget with Card widget to make the cards inside the Container.
Card(child: ListTile());
Demo
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MyHome());
}
class MyHome extends StatelessWidget {
const MyHome({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Ans(),
);
}
}
class Ans extends StatefulWidget {
const Ans({super.key});
#override
State<Ans> createState() => _AnsState();
}
class _AnsState extends State<Ans> {
List<String> charName = [
'Rio',
'Tokyo',
'Berlin',
'Stockhome',
'Lisbon',
'Sergio',
'Martin'
];
List<String> charGender = [
'male',
'female',
'male',
'female',
'female',
'male',
'male'
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Tile Wrapper"),
),
body: SizedBox(
height: double.infinity,
width: double.infinity,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Container(
height: 400,
width: 300,
/// Clipping the inner View Condition
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.2),
border: Border.all(color: Colors.black),
color: Colors.amberAccent,
),
child: ListView.builder(
itemCount: charGender.length,
itemBuilder: ((BuildContext context, int index) {
return Padding(
padding: EdgeInsets.only(top: 20.0),
//// Wrap the ListTile with Card Widget...
child: Card(
child: ListTile(
title: Text(
charName[index],
style: TextStyle(fontSize: 18.0),
),
subtitle: Text(
charGender[index],
style: TextStyle(fontSize: 18.0),
),
tileColor: Colors.brown,
leading: CircleAvatar(
radius: 20, child: Icon(Icons.person_rounded)),
),
),
);
})),
),
),
],
),
),
);
}
}
Sample

How to display loading widget until a main widget is loaded

I am using the animation package to create a popup modal However building the widget inside the model is very noticeably slow and is making making the popup take time to open. I am trying to put a loading indicator when opening the modal then build the widget afterward and just update.
I am lost on how to accomplish that.. it would be highly appreciated if someone could help.
this is the animation package method for the modal
ElevatedButton(
onPressed: () {
showModal<void>(
context: context,
builder: (BuildContext context) {
// building _ExampleAlertDialog takes time
return _ExampleAlertDialog(loading: loading);
},
).then((state) => setState(() => {loading = !loading}));
},
child: const Text('SHOW MODAL'),
),
the _ExampleAlertDialog is supposed to be a listView
class _ExampleAlertDialog extends StatefulWidget {
_ExampleAlertDialog({
this.loading,
});
final bool loading;
#override
__ExampleAlertDialogState createState() => __ExampleAlertDialogState();
}
class __ExampleAlertDialogState extends State<_ExampleAlertDialog> {
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 50, horizontal: 20),
child: Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Material(
child: Column(
children: [
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context).dividerColor))),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Icon(Icons.arrow_back), Icon(Icons.refresh)],
),
),
// This is the Listview I am trying to avoid onLoad
Expanded(child: widget.loading == true ? Container():
ListView.builder(
itemCount: 16,
itemBuilder: (BuildContext ctxt, int index) {
return Container(
// width: MediaQuery.of(context).size.width * 1,
child: Row(
children: <Widget>[
Icon(
Icons.radio_button_unchecked,
color: Colors.blue,
size: 12.0,
),
SizedBox(
width: 20.0,
),
Text(
"Travetine",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400),
),
],
),
);
},
)
)
],
),
),
),
),
);
}
}

How to get all documents that are inside of a collection that is inside of another collection on Firestore?

Well, I'm trying to build a function that when I click in a favorite icon I am choosing a place as one of my favorite places. And if I want to see my favorite places, I need just go to the favorite page that should return all my favorite places. I have two favorite places stored on my firestore. When I'm trying to get them, returns nothing... And that's the problem.
Each favorite document, contains fields like city, image etc. Here's my database: https://i.imgur.com/CmTr4vG.png
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class Favorites extends StatefulWidget {
#override
_FavoritesState createState() => _FavoritesState();
}
class _FavoritesState extends State<Favorites> {
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
dynamic loadFavorites() async{
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final dynamic userUid = user.uid;
return userUid;
}
dynamic document = loadFavorites();
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 30.0, bottom: 5.0),
child: Text("Favoritos",
style: TextStyle(fontSize: 20),
textAlign: TextAlign.center,
),
),
Container(
child: FutureBuilder<QuerySnapshot>(
future: Firestore.instance.collection("users").document(document.toString()).collection("favorites").getDocuments(),
builder: (context, snapshot){
if(!snapshot.hasData){
return Center(child: CircularProgressIndicator());
}else{
return snapshot.data.documents.isEmpty ? Center(child: Text("Nenhum favorito escolhido.")) : ListView.builder(
physics: const NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index){
return Container(
padding: EdgeInsets.all(10.0),
child: buildFavorite(width, height, snapshot.data.documents[index]),
);
},
);
}
},
),
),
],
),
),
);
}
Widget buildFavorite(double width, double height, DocumentSnapshot document){
return Container(
padding: EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey,
offset: Offset(1.0, 1.0),
blurRadius: 10.0,
),
],
borderRadius: BorderRadius.circular(10.0),
),
child: Stack(
children: <Widget>[
//Padding(padding: EdgeInsets.only(top: 100),),
Container(
margin: EdgeInsets.only(bottom: 20.0, left: 20.0),
child: Text(document["title"], style: TextStyle(fontSize: 18),),
),
Container(
width: width * 0.37,
height: height * 0.18,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(document["image"]),
),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey,
offset: Offset(1.0, 1.0),
blurRadius: 1.0,
),
],
),
margin: EdgeInsets.only(left: width * 0.60),
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 30.0),
child: Icon(Icons.location_on, color: Colors.red,),
),
Container(
margin: EdgeInsets.only(left: 10.0, top: 30.0),
child: Text(document["text"]),
),
],
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 60.0),
child: Icon(Icons.phone, color: Colors.red),
),
Container(
margin: EdgeInsets.only(left: 10.0, top: 60.0),
child: Text(document["phone"]),
),
],
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 90.0),
child: Icon(Icons.timer, color: Colors.red,),
),
Container(
margin: EdgeInsets.only(left: 10.0, top: 90.0),
child: Text(document["time"]),
),
],
),
],
),
);
}
}
Your Problem lies here:
future: Firestore.instance.collection("users").document(document.toString()).collection("favorites").getDocuments(),
document.toString() will return Instance of Future<dynamic> since the actual type of this variable is the return type of your loadUser() function which is Future<dynamic> and the toString() method of objects is usually Instance of CLASS_NAME. Generally I strongly recommend you to make use of the type safety of dart by always using explicit types instead of dynamic! Errors occuring while using types indicate that something you are trying is not correct and better helps to understand what kind of value is to be expected.
You are trying to retrieve the userUid to use it inside your FutureBuilder but unfortunately this function needs to be async since you have to get it from Firebase. The surrounding function (build of your Widget) is not async. Therefore you can't resolve the loadUser() function as you intend to. To fix this issue you need to extract the userUid and favorites retrieval outside your build function - let me show you an example:
Future<QuerySnapshot> getFavoritesFromUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
final String userUid = user.uid;
return Firestore.instance.collection("users").document(userUid).collection("favorites").getDocuments();
}
#override
Widget build(BuildContext context) {
...
Container(
child: FutureBuilder<QuerySnapshot>(
future: this.getFavoritesFromUser()
...