In FutureBuilder, I need to create Wrap with elements but I don't know how.
FutureBuilder(
future: _getCategories(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.data == null){
return Text("Wait...");
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index){
return Text(snapshot.data[index].category);
},
);
}
},
)
I need to replace ListView.builder with something like Wrap.builder or something else.
Let's say this is your List:
List<int> _items = List.generate(10, (i) => i);
You can use it in Wrap:
Using List.map
Wrap(
direction: Axis.vertical,
children: _items.map((i) => Text('Item $i')).toList(),
)
Using for-each
Wrap(
direction: Axis.vertical,
children: [
for (var i in _items)
Text('Item $i'),
],
)
To answer your question:
Wrap(
children: snapshot.data.map((item) => Text(item.category)).toList().cast<Widget>(),
)
Here's a solution,
List tags = ['one','two'];
Wrap(
children: [
for (var item in tags)
Padding(
padding: const EdgeInsets.all(8.0),
child: Chip(
label: Text(item),
),
)
],
),
Related
I want to show a list of comments and so far i have achieve
Code is as below:
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: CommentList(
commentStream: commentBloc.commentStream!,
articleId: widget.articleId!,
),
),
...
and the code for CommentList is:
return StreamBuilder<QuerySnapshot>(
stream: commentStream,
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data!.docs.length > 0
? ListView.builder(
padding: EdgeInsets.only(bottom: 15.0),
reverse: true,
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data!.docs[index];
return CommentTile(
comment: ds["comment"],
commentterName: ds["commentedBy"],
timeAgo: ds["commentAt"],
avatar: ds["avatarUrl"],
);
})
...
How i can achieve this ?
There is a reverse option inside the listview.builder() widget make it true
I have an ExpansionPanelList inside a ListView and I'm unable to get it to scroll when trying in the middle of the screen, though it will work on the edges. I've attached the code below. I'm guessing its the ExpansionPanelList that isn't letting me scroll but I'm not sure why because the items are inside a ListView as well.
I've taken a video of the issue https://drive.google.com/file/d/19zM7cfjshcN8OfEbRhvxIgmUp8sq1TP6/view?usp=sharing
_bodyBuilder() {
return
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(15.0),
children: <Widget>[
ExpansionPanelList.radio(
initialOpenPanelValue: 2,
children: dateList.map<ExpansionPanelRadio>((DateTime date) {
return ExpansionPanelRadio(
canTapOnHeader: true,
value: date.day,
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(DateFormat('dd/MM/yyyy').format(date)),
);
},
body: Container(
//child: ListView.separated(
child: ListView.builder(
shrinkWrap: true,
itemCount: cleanRecords
.where((Log) =>
DateTime.parse(DateFormat('yyyy-MM-dd')
.format(Log.time.toDateTime()))
.toString() ==
date.toString())
.toList()
.length,
itemBuilder: (context, index) {
final records = cleanRecords
.where((Log) =>
DateTime.parse(DateFormat('yyyy-MM-dd')
.format(Log.time.toDateTime()))
.toString() ==
date.toString())
.toList();
final schedule = records[index];
return ListTile(
title: Text(DateFormat('hh:mm').format(schedule.time.toDateTime())),
subtitle: Text(schedule.notes),
onTap: () => _updateRecord(schedule.parentID, schedule.id),
);
},
// separatorBuilder: (context, index) {
// return Divider();
// },
),
),
);
}).toList(),
)
],
);// ListTiles++
}
i implemented listView in flutter and it shows product count=5 , but i wanted these 5 items to be generated randomly , is there a way to do it? thanks in advance
ps: i tried code depending on answer below but it gives me error count!=null
Expanded(
child: SizedBox(
height: 210.0,
child: FutureBuilder(
future: httpService.getProducts(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text('Loading...'),
),
);
} else if (snapshot.data.length == 0) {
return Container(
child: Center(
child: Center(
child: Text('No offers'),
),
),
);
} else {
var rndItems = snapshot.data.shuffle();
return ListView.separated(
separatorBuilder:
(BuildContext context, int index) {
return SizedBox(height: 3);
},
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: rndItems ,
itemBuilder: (ctx, i) => (PdtItem(
title: snapshot.data[i].title,
imgUrl: snapshot.data[i].imgUrl,
price: snapshot.data[i].price,
pdt2: snapshot.data[i])),
);
If you want the items from snapshot.data to be listed in a random order then you may shuffle the data as follows :
....
snapshot.data.shuffle();
....
If you want to display random number of items everytime then
....
import 'dart:math';
....
var rng = new Random();
var rndItems = rng.nextInt(snapshot.data.length);
....
.....
scrollDirectionn: Axis.horizontal,
shrinkWrap: true,
itemCount: rndItems,
itemBuilderr: (ctx, i) => (PdtItem(
.....
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: data[1].store.length,
itemBuilder: (BuildContext context, int index) {
return Wrap(
children: [
Text(data[1].store[index].number.toString()),
],
);
},
),
);
}
I used ListView.builder, I want to wrap Horizontal & scroll Vertical,.
I spend a lot of time on this stack...
My data from local JSON, with Future Builder and return to ListView.builder...
please see attach..
Thanks All...
Replace your Container with the below code.
SingleChildScrollView(
child: Column(
children: [
Wrap(
children: List<Widget>.generate(
1000,
(int index) {
return Text(index.toString() + ' ');
},
),
)
],
)),
Hi I am trying to list data from JSON to Listview Builder . But Flutter is giving me this error: Column's children must not contain any null values, but a null value was found at index 0
I tried to map each one like this inside the listview
alo[Index]['rewards'].forEach((k, v) {
Text(v['name']);
}),
Here is my full code:
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards'].forEach((k, v) {
Text(v['name']);
}),
],
),
));
});
Is there any solution to this? Thank you!
The thing is forEach() doesn't return anything, you could use map() instead, like this:
children: alo[Index]['rewards'].values.map<Widget>((v) => Text(v['name'])).toList()
If you want to add more widgets, you could do something like this:
Column(
children: <Widget>[
Column(
children: alo[Index]['rewards']
.values
.map<Widget>((v) => Text(v['name']))
.toList(),
),
Text('Other widget'),
],
)
You have two options, if you don't have any rewards then you can
a) Leave an empty card
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards']!=null?
alo[Index]['rewards'].forEach((k, v) {
return Text(v['name']);
}):SizedBox()
],
),
));
});
or
b) don't render any card
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return alo[Index]['rewards']!=null?Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards'].forEach((k, v) {
return Text(v['name']);
}),
],
),
)):SizedBox();
});