******Update ********
Here's the updated body which resolved the scrolling issue as posted earlier below, but now getting A RenderFlex overflowed by 620 pixels on the bottom. I replaced body: listView with body: Column. I know this is very common issue and per the logcat the solution is to wrap the content in Expanded widget. In my case, I would like to know where to use 'Expanded` widget to resolve the issue.
Widget reviewsSection = Container(
child: FutureBuilder(
future: _fetchReviews(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return _buildReviewTiles(snapshot.data);
} else if (snapshot.hasError) {
return Text('${snapshot.error}',
style: TextStyle(color: Colors.black, fontSize: 12.0),
textAlign: TextAlign.justify);
}
// By default, show a loading spinner
return new Container(child: new CircularProgressIndicator());
}));
// Creates a list view based on the reviews in the reviewList.
Widget _buildReviewTiles(List<Review> list) {
return (new Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: reviewList == null ? 0 : reviewList.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: Center(
child: Column(children: <Widget>[
_getReviewTile(reviewList[index]),
new Padding(
padding: EdgeInsets.all(5.0),
),
new Divider(
height: 3.0,
color: Colors.black26,
)
])));
}),
));
}
// Returns a list tile representation of a review
Widget _getReviewTile(Review review) {
// Keep only the day, month, and year
var date = review.created.split(" ")[0];
return new Container(
color: Colors.yellow,
child: new Row(
children: <Widget>[
new Expanded(
child: ListTile(
leading: new Column(children: <Widget>[
const Icon(Icons.stars),
]),
subtitle: new Text(
'${review.review}',
style: TextStyle(color: Colors.black, fontSize: 14.0),
),
title: new Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(date, style: new TextStyle(fontSize: 12.0)),
new Padding(
padding: EdgeInsets.all(4.0),
),
],
),
),
new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new StarRating(
starCount: 5,
rating: review.rating + 0.0,
color: Colors.amber,
),
]),
],
),
),
),
],
),
);
}
This is my Scaffold code that uses reviewsSection along with other sections:
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: FadeInImage.assetNetwork(
placeholder: 'assets/header_bg.png',
width: 600.0,
height: 240.0,
fit: BoxFit.cover,
image: 'https:' + pro.profilePhoto),
),
),
];
},
body: Column(
children: <Widget>[
new Container(
color: Colors.black87,
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: new EdgeInsets.fromLTRB(5.0, 8.0, 10.0, 5.0),
),
new Text(
'${pro.fullname}',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
new Text(
'${pro.company}',
style: TextStyle(fontSize: 14.0, color: Colors.white),
),
Padding(
padding: EdgeInsets.all(5.0),
)
],
),
),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: new EdgeInsets.fromLTRB(5.0, 8.0, 10.0, 5.0),
),
new StarRating(
starCount: 5,
rating: pro.rating,
color: Colors.amber,
),
new Text(
'${pro.reviewCount} reviews',
style: TextStyle(fontSize: 14.0, color: Colors.white),
),
Padding(
padding: EdgeInsets.all(5.0),
)
],
),
],
),
),
Padding(
padding: EdgeInsets.all(5.0),
),
buttonSection,
Padding(
padding: EdgeInsets.all(2.0),
),
Divider(color: Colors.black26, height: 0.5),
Padding(
padding: EdgeInsets.all(4.0),
),
experienceSection,
Padding(
padding: EdgeInsets.all(8.0),
),
reviewsSection
],
),
),
);
}
Am re-posting the answer suggested by #anmol.majhail that helped me to resolve the issue.
"Try Wraping - reviewsSection in Expanded.& Remove containers around FutureBuilder & ListViewBuilder"
So corrected reviewsSection code that worked is:
Widget reviewsSection = Expanded(
child: FutureBuilder(
future: _fetchReviews(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return _buildReviewTiles(snapshot.data);
} else if (snapshot.hasError) {
return Text('${snapshot.error}',
style: TextStyle(color: Colors.black, fontSize: 12.0),
textAlign: TextAlign.justify);
}
// By default, show a loading spinner
return Center(child: CircularProgressIndicator());
}));
Related
There're two questions.
01.
I want to show more rows of icons with one List only. As you see from Fig3, I'm using three rows in Expand widget, in Card, and each row has the corresponding List. I think it was not so nice to build like this way.
02.
Which widget will be more suitable to build blocks view Github in Flutter?
Fig1.
Fig2.
Fig3.
body: Container(
child: Column(
children: <Widget>[
Text('TrahsCollection',
style: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold, fontSize: 13),
),
Flexible(
child: ListView.builder(
itemCount: _item.length,
itemBuilder: (BuildContext context, int index) {
final String item = _item[index];
final MaterialColor = Colors.blue;
return Container(
margin: const EdgeInsets.only(top: 5.0),
child: Card(
margin: EdgeInsets.all(5),
elevation: 10,
child: Row(
children: <Widget>[
Expanded(
flex:2,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.amber[300],
child: Text("Pop"),
),
),
),
const Expanded(
flex:3,
child: ListTile(
title: Text("Title", style: TextStyle(fontSize: 20),),
subtitle: Text("SubTitle"),
),
),
Expanded(
flex:3,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
children: scoreKeeper,
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
children: scoreKeeper,
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
children: scoreKeeper,
),
),
],
),
),
],
),
)
);
},
),
)
],
),
),
Your building approach is okey, but you should move your peaces of code to separated widgets
You can use GridView
When I try to put buildProfileHeader() inside the children of a ListView, I get the error type Future<dynamic> is not a subtype of type Widget
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: cabecera(context, titleText: "Perfil"),
body: ListView(
children: [buildProfileHeader()],
),
);}}
Here's the code for the buildProfileHeader
buildProfileHeader() async {
return FutureBuilder<DocumentSnapshot>(
future: usersRef.doc(widget.profileId).get(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return cargandoCircular();
}
User user = User.fromDocument(snapshot.data);
return Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
CircleAvatar(
radius: 40.0,
backgroundColor: Colors.grey,
backgroundImage:
CachedNetworkImageProvider(user.photoUrl),
),
Expanded(
flex: 1,
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildCountColumn("publicaciones", 0),
buildCountColumn("seguidores", 0),
buildCountColumn("siguiendo", 0),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
buildProfileButton(),
],
),
],
),
),
],
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 12.0),
child: Text(
user.username,
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0),
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 4.0),
child: Text(
user.displayName,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 2.0),
child: Text(
user.bio,
),
),
],
),
);
});}
children expects a list of Widgets. What you're doing here with buildProfileHeader is that you've marked it as async, which means it will return a Future value instead.
It doesn't seem like you actually need this function itself to be async, so just go ahead and remove that from the method signature
buildProfileHeader() {
return FutureBuilder<DocumentSnapshot>(
future: usersRef.doc(widget.profileId).get(),
// ...
This is my code
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 200.0,
title: AppAbar(),
flexibleSpace: FlexibleSpaceBar(
background: FlexibleAppBar(),
),
leading: Icon(Icons.menu, color: Colors.white, size: 30.0,),
),
SliverList(
delegate: SliverChildListDelegate(
List.generate(6, (idx) {
return Padding(
padding: const EdgeInsets.all(5.0),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
elevation: 3,
margin: EdgeInsets.symmetric(horizontal: 15),
child: Consumer<TimeSheetRepository>(
builder: (BuildContext context, TimeSheetRepository db, Widget child) {
_queryWeekYear = db.queryByMonthYear(
12, 2020);
return StreamBuilder(
stream: _queryWeekYear,
builder: (context, snapshot){
if(!snapshot.hasData || snapshot.data.documents == null) return CircularProgressIndicator();
return ListTile(
leading: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${_numWeeks[idx]}'),
],
),
title: Container(
height: MediaQuery.of(context).size.height/16,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 7,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Column(
children: [
Text('${(DateFormat('EEEE').format(firstweek[index]).substring(0, 1))}',style: TextStyle(fontSize: 12.0, color: Colors.black54)),
],
),
SizedBox(width: 28.0),
],
),
]
),
);
}
),
),
subtitle: Container(
height: MediaQuery.of(context).size.height/20,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot docSnapshot = snapshot.data.documents[index];
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Column(
children: [
Text('${docSnapshot['date'].toString()}',style: TextStyle(fontSize: 12.0, color: Colors.black54)),
**// HERE I'M TRYING TO PUT THE DATE (IF EXISTS IN MY QUERY) BUT I NEED PUT IT IN THE CORRECT DAY IN MY CARD**
],
),
SizedBox(width: 28.0),
],
),
]
);
}
)
),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColorLight.withOpacity(0.2),
borderRadius: BorderRadius.circular(5.0),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text( "148", style: TextStyle(color: Colors.blue.shade800, fontWeight: FontWeight.w500, fontSize: 18.0),
),
),
),
],
),
);
}
);
}
),
),
);
})
),
),
],
),
);
I built a card, inside I have a listview.buider making a days of the weeks, and I have my Stream with QuerySnapshot with some days. I'm trying to put in my widget day, the same day that I have in my QuerySnapshot.
How can I get a specify date from my query?
I did some changes, but doesn't works.
I need to find inside my QuerySnapshot if X day is there, if not continue next
I am trying to display Listview using Listview builder below the purple color(as seen in the image)container with the below code:
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: 300,
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(75.0)),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 200, 0),
child: Container(
padding: EdgeInsets.fromLTRB(0, 30,200,0),
child: IconButton(icon: Icon(Icons.arrow_back,),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
),
),
),
SizedBox(height: 20,),
Text('Semester 1',
style: TextStyle(color: Colors.white,
fontSize: 30),
)
],
)
),
Container(
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: new Text("hello"),
padding: const EdgeInsets.all(20),
))
],
)));
}),
)
],
),
);
It returns a blank screen after running the code,without showing any error. I am not able to figure out the problem.
Please help!
If you use listview is small and inside Column then you should add
shrinkWrap: true in ListView
Column(
children: <Widget>[
ListView(
shrinkWrap: true, // use it
)
],
)
Or If your ListView Height is fix then use
Column(
children: <Widget>[
SizedBox(
height: 200, // constrain height
child: ListView(),
)
],
)
or If you want to fill all remaining space the use
Column(
children: <Widget>[
Expanded(
child: ListView(...),
)
],
)
Simply wrap the ListView in Expanded. The error here is that ListView doesn't know how to size itself (it has unbounded height from the Column). Using Expanded will tell it to fill up all the remaining space and fix the sizing problem
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: 300,
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(75.0)),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 200, 0),
child: Container(
padding: EdgeInsets.fromLTRB(0, 30,200,0),
child: IconButton(icon: Icon(Icons.arrow_back,),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
),
),
),
SizedBox(height: 20,),
Text('Semester 1',
style: TextStyle(color: Colors.white,
fontSize: 30),
)
],
)
),
Container(
child: Expanded( // <-- wrap with expanded
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: new Text("hello"),
padding: const EdgeInsets.all(20),
))
],
)));
}),
),
)
],
),
);
Error is caused by Container that is wrapping ListView. You need to specify bounds for that Container.
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: 300,
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius:
BorderRadius.only(bottomLeft: Radius.circular(75.0)),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 200, 0),
child: Container(
padding: EdgeInsets.fromLTRB(0, 30, 200, 0),
child: IconButton(
icon: Icon(
Icons.arrow_back,
),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
),
),
),
SizedBox(
height: 20,
),
Text(
'Semester 1',
style: TextStyle(color: Colors.white, fontSize: 30),
)
],
),
),
Container(
height: 300,
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Card(
child: Container(
child: Text("hello"),
padding: const EdgeInsets.all(20),
))
],
)));
}),
)
],
),
Above code should be working. Please note that, you don't need to specify "new" keyword in flutter.
I'm trying to build a ListView but I can't do that my list hit the bottom without overflowing it, the way that I found to work was setting the height on a container, but, when I use my personal device I got a big white space below my list.
I already tried the flexible and expanded widgets before the list, but neither worked, I always get the same errors:
RenderFlex children have non-zero flex but incoming height constraints are unbounded
Vertical viewport was given unbounded height error
Do you have any solutions for this?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.blueAccent,
title: Padding(
padding: EdgeInsets.only(left: 5.0),
child: Text(
user.name,
style: TextStyle(fontSize: 30.0),
),
),
actions: <Widget>[
IconButton(
alignment: Alignment.center,
icon: Icon(Icons.forward),
onPressed: () {},
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
color: Colors.blueAccent,
child: Padding(
padding: EdgeInsets.only(top: 30.0, left: 20.0, right: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Conta",
style: TextStyle(fontSize: 17.0, color: Colors.white)),
Divider(color: Colors.blueAccent),
Text("${user.bankAccount} / ${user.agency}",
style: TextStyle(fontSize: 30.0, color: Colors.white)),
Padding(
padding: EdgeInsets.only(top: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Saldo",
style:
TextStyle(fontSize: 17.0, color: Colors.white)),
Divider(color: Colors.blueAccent),
Text("${user.balance}",
style:
TextStyle(fontSize: 30.0, color: Colors.white)),
Divider(color: Colors.blueAccent),
],
),
),
],
),
),
),
Divider(color: Colors.white),
Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Recentes",
style: TextStyle(fontSize: 20.0, color: Colors.black)),
FutureBuilder(
future: getuserStatement(user.userId),
builder: getstatements,
),
],
),
),
],
),
);
}
Future getuserStatement(int id) {
return api.getUserExtract(id);
}
Widget getstatements(BuildContext context, AsyncSnapshot snapshot) {
return !snapshot.hasData
? Center(child: CircularProgressIndicator())
: Container(
height: 340,
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
print(snapshot.data[index].title);
return Card(
elevation: 5,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10.0, left: 10.0),
child: Row(
children: <Widget>[
Text(snapshot.data[index].title),
Expanded(
child: Align(
alignment: Alignment(0.90, 0.00),
child: Text(snapshot.data[index].date),
),
),
],
),
),
Padding(
padding:
EdgeInsets.only(top: 20.0, bottom: 10.0, left: 10.0),
child: Row(
children: <Widget>[
Text(snapshot.data[index].desc),
Expanded(
child: Align(
alignment: Alignment(0.90, 0.00),
child:
Text(snapshot.data[index].value.toString()),
),
),
],
),
)
],
),
);
},
),
);
}
}
Solution:
after spending so much time on this, i found the solution:
i saw that on this part of my code i put another column inside a padding:
Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Recentes",
style: TextStyle(fontSize: 20.0, color: Colors.black)),
Expanded(
child: FutureBuilder(
future: getuserStatement(user.userId),
builder: getstatements,
),
),
],
),
),
so what i did was, just removed the Column and left the Text widget and put the expanded widget below the padding.
Padding(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: Text("Recentes",
style: TextStyle(fontSize: 20.0, color: Colors.black)),
),
Expanded(
child: FutureBuilder(
future: getuserStatement(user.userId),
builder: getstatements,
),
),
that created my list with the maximum space of the device, with this i don't need to set a height with Container or a sizedBox.
In my vision, i think that happens cause i put a list inside a Column that already is inside a column, so the list doesn't known how much space she has