Using Wrap, and Chips inside of ListView - flutter

I am trying to have a list of data that is being returned by firebase basically represented on screen as a collection of filterable tags. The problem is when using wrap inside of my list view I am still get just a horizontal list of chips.
Light Grey is what I am after, dark grey is what is being returned
FutureBuilder _buildSubCategories() {
return FutureBuilder(
future: cats
.doc(widget.catId)
.collection('sub-categories')
.orderBy('name')
.get(),
builder: (ctx, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator.adaptive());
} else {
return ListView.builder(
itemCount: snapshot.data.docs.length,
physics: const NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, idx) {
// DocumentSnapshot cat = snapshot.data.docs[index];
return Wrap(
children: snapshot.data.docs
.map((item) => ActionChip(
label: Text(item['name']),
))
.toList()
.cast<Widget>(),
);
});
}
});
}

You do not need to use list view for that. You could simply use Wrap. Wrap widget pushes the overflown widget to next line
Example:
FutureBuilder _buildSubCategories() {
return FutureBuilder(
future: cats
.doc(widget.catId)
.collection('sub-categories')
.orderBy('name')
.get(),
builder: (ctx, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator.adaptive());
} else {
return Wrap(
children: snapshot.data.docs
.map((item) => ActionChip(
label: Text(item['name']),
))
.toList()
.cast<Widget>(),
);
}
});
}

Related

Is there any way to make it -> snapshot.data[index].variable in flutter?

In flutter if i wanted to print the values using FutureBuilder
I have to write this 3 line individually
snapshot.data[index].courseName ,
snapshot.data[index].coursePrice,
snapshot.data[index].aboutCourse
So, Is there any way to make a list like this -> fieldItem = ['courseName' , 'coursePrice' , 'aboutCourse'] and then pass fieldItems after the .data[index].{our varibles}
**snapshot.data[index].fieldItems**
varibles will be passed through the fieldItem.
Sorry for my bad english
body: FutureBuilder(
future: _loadData(),
builder: (BuildContext ctx, AsyncSnapshot<List> snapshot) {
if(snapshot.hasData) {
// You can make variable here
// final _data = snapshot.data;
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, index) {
// Or as in your case
final _data = snapshot.data![index];
return Card(
margin: const EdgeInsets.all(10),
// render list item
child: ListTile(
contentPadding: const EdgeInsets.all(10),
title: Text(_data['title']),
subtitle: Text(snapshot.data![index]['body']),
),
),
}
);
} else {
return const Center(child: CircularProgressIndicator());
}
}
);
Refer 11th line, if it helps, upvote.

my list of array snapshot is in vertical flutter

I try to get the snapshot of an array and I get it But when I display it in my app It’s in vertical as describe in the
image:
And This is the normal one in my cloud firestore (I want to display it in an horizontal ofcourse)
And here's the
code:
StreamBuilder(
stream: FirebaseFirestore.instance
.collection("groups")
.doc(groupId)
.snapshots(),
builder: (context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
var userDocument = snapshot.data?["members"];
if (!snapshot.hasData) {
return Container();
}
return ListView.builder(
//physics: const BouncingScrollPhysics(),
itemCount: userDocument.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection("users")
.doc(userDocument[index])
.snapshots(),
builder: (context, snapshot1) {
var userDocument = snapshot1.data?['fullName'];
if (snapshot1.data == null) {
return const Text('No Data');
}
return ListView.builder(
itemCount: userDocument.length,
shrinkWrap: true,
itemBuilder: (context, index) {
//Where I display the name in app
return Center(
child:
Text(userDocument[index]));
});
});
});
})
Please take a look at the code
Give your ListView.builder a height by wrapping it inside a SizedBox.
Then inside your ListView.builder, there is a parameter scrollDirection: Axis.horizontal,. Next, you can disable scrolling too.

Flutter combine futuerbuilder and streambuilder

i need some guidance how to combine a futurebuilder with a streambuilder. For example, the futurebuilder will load the comments which are stored in my Mysql database, while the streambuilder will fetch new comments and add them to the listview. The stream and future works perfectly, but i have no idea how i will combine these two things with eachother.
FutureBuilder(
future: _fetchComments(39),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
return Container(
height: 150,
child: StreamBuilder(
stream: commentProvider.channel.stream,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot2) {
return ListView.builder(
key: PageStorageKey("CommentsScroll"),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
final comment = snapshot.data[index];
return CommentTile(
key: Key(DateTime.now().toString()),
photoUrl: comment["photo_url"],
displayName: comment["display_name"],
created: comment["created"],
text: comment["text"],
);
},
);
},
),
);
},
),

Display N numbers of uid from firestore i am new to flutter

I want to retrive all the users from firestore and display it and perform some action how can i achieve it
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('Loading Data');
return ListView(
children: <Widget>[
ListTile(
// Text(snapshot.data.documents[0]['uid']),
title: Text(snapshot.data.documents[0]['fname']),
onTap: () {})
],
);
},
);```
You need something like this:
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('Loading Data');
List<DocumentSnapshot> snapshotDocuments = snapshot.data.documents;
return ListView.builder(
itemCount: snapshotDocuments.length,
itemBuilder: (context,index){
return ListTile(
// Text(snapshotDocuments.documents[index]['uid']),
title: Text(ssnapshotDocuments.documents[index]['fname']),
onTap: () {})
}
);
},
);
You can read more about ListView.builder and ListView class here.
What the code above does is that it uses the itemCount (it calls itemBuilder that many times) which is equal to the length of snapshotDocuments.length. it passes the index to the itemBuilder function and you can use that index to loop through your documents and show the data.
Since this stream will return a list of all documents you can use ListView.builder widget which builds list according to some length i.e in this scenario it will build list according to length of users present in database.
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('Loading Data');
return ListView.builder(
itemCount: snapshot.data.length;
itemBuilder: (context,index){
return ListTile(
// Text(snapshot.data.documents[0]['uid']),
title: Text(snapshot.data.documents[index]['fname']),
onTap: () {});
}
);
},
);

Flutter: When the snapshot is empty the widget disappears

I am trying to build a search list, the list is working fine but if the result is empty i need to show no data. I tried the following code but the widget holds for a second and then disappear
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: Container(
child: Text('No Data Found.'),
),
);
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
})
Can anyone help me with this.
Thank you in advance.
I just write the code as below and it works.
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('length of list ${searchResult.length}');
if (searchResult.length==0) {
return Center(
child: Text('No data'),
);
}
else if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
}),
In your Code in Else part before - return ListView.builder- add the following code.
...
else {
if (searchResult.length == 0)
{
return Center(child: const Text('No Date'));
}
return ListView.builder .....