Dynamic height of listview builder item - flutter

I am unable to set the dynamic size to my list item of list view builder, every time it shows blank screen and when I specify a constant size it works.
I tried by using column by setting mainAxisSize=minimum and by using container as we know container wraps the child height but nothing works
listItem (GuideLines news) =>Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[Container(
decoration: BoxDecoration(image: new DecorationImage(image: AdvancedNetworkImage(
"${news.featured_image}",
useDiskCache: true,
cacheRule: CacheRule(maxAge: const Duration(days: 7)),
),fit: BoxFit.cover)),
margin: EdgeInsets.only(bottom: 10.0),
child: ListTile(
onTap: (){
print(news.web_link);
Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
},
title: new Container(
margin: EdgeInsets.only(left: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: new Text("${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}", style: TextStyle(fontFamily: 'SF-Display-Regular' ,fontSize: 13.0 ,color: Colors.white),),
),
SizedBox(height: 13.0),
new Flexible(
child: new Container( width: MediaQuery.of(context).size.width *0.45,
child: Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: new Text("${news.title}" ,maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(fontFamily: 'SF-Display-Semibold' ,fontSize: 22.0 ,color: Colors.white),),
)
),
)
],
)),
trailing: Padding(
padding: const EdgeInsets.only(right: 20),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[Icon(Icons.arrow_forward_ios, color: Colors.white),SizedBox(width: 8,)],
),
),
),
)],
);

Just add these two properties of shrinkWrap and physics to make the height of list dynamic
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), //Optional
itemCount: size,
itemBuilder: (context, position) {}
),

The problem with your code is, that you used a Flexible widget in a Column. A Flexible widget expands to the remaining space of the Column or Row. However, this only works if you have restricted the size of the Column or Row widget. Because otherwise, the size of the element in the Column would expand to infinity as the remaining space is not restricted and therefore also infinity.
When using Flexible or Expanded widgets you always need to restrict their parent size, else you get this error:
RenderFlex children have non-zero flex but incoming height constraints
are unbounded. When a column is in a parent that does not provide a
finite height constraint, for example if it is in a vertical
scrollable, it will try to shrink-wrap its children along the vertical
axis. Setting a flex on a child (e.g. using Expanded) indicates that
the child is to expand to fill the remaining space in the vertical
direction.
The solution and some cleanup of your code:
Widget listItem(GuideLines news) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AdvancedNetworkImage(
"${news.featured_image}",
useDiskCache: true,
cacheRule: CacheRule(maxAge: const Duration(days: 7)),
),
fit: BoxFit.cover),
),
margin: EdgeInsets.only(bottom: 10.0),
child: ListTile(
onTap: () {
print(news.web_link);
Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
},
title: Container(
margin: EdgeInsets.only(left: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0, bottom: 13.0),
child: Text(
"${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}",
style: TextStyle(fontFamily: 'SF-Display-Regular', fontSize: 13.0, color: Colors.white),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.45,
padding: const EdgeInsets.only(bottom: 20.0),
child: new Text(
"${news.title}",
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontFamily: 'SF-Display-Semibold', fontSize: 22.0, color: Colors.white),
),
)
],
),
),
trailing: Padding(
padding: const EdgeInsets.only(right: 28),
child: Icon(Icons.arrow_forward_ios, color: Colors.white),
),
),
);
}
In your specific case, this Flexible widget was redundant anyway.

Related

RenderFlex children have non-zero flex but incoming width constraints are unbounded - Flutter

I'm trying to show cart items horizontally using listview builder but it is throwing up following error
RenderFlex children have non-zero flex but incoming width constraints are unbounded (When a row is in a parent that does not provide a finite width constraint, for example if it is in a horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the horizontal direction.)
I already wrapped the list view builder with defined height but still throwing up the error
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('MY CART', style: GoogleFonts.oswald(color: Colors.black, fontSize: 18.0, fontWeight: FontWeight.w400)),
const SizedBox(height: 20.0),
SizedBox(
height: 180.0,
width: double.infinity,
child: ListView.builder(
itemCount: 2,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index){
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 150.0,
width: 150.0,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/dress.jpg')
),
borderRadius: BorderRadius.all(Radius.circular(15.0))
),
),
const SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('PRODUCT TITLE',
style: GoogleFonts.oswald(
textStyle: const TextStyle(
color: Colors.black,
fontSize: 14.0)), overflow: TextOverflow.visible,),
const SizedBox(height: 5.0),
Text('SIZE: M',
style: GoogleFonts.oswald(
textStyle: const TextStyle(
color: Colors.black45,
fontSize: 16.0))),
const SizedBox(height: 10.0),
Text('10 DOLLARS',
style: GoogleFonts.oswald(
textStyle: const TextStyle(
color: Colors.black,
fontSize: 16.0))),
],
),
)
],
);
},
),
),
],
)
This was happened because you use expanded in row inside horizontal listview, you have two option :
One: remove the expanded widget inside Row inside itemBuilder.
Two: set width for item inside itemBuilder:
itemBuilder: (context, index){
return SizedBox(
width: 400.0, // <--- add this
child: return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 150.0,
...
);
}

How to make list view builder scrollable and set its height space as much as it can take?

I have a problem with ListView. I need to make it scrollable and set its size to max space it can take. Below listView I have a button that should be visible, but the ListView covers it.
I tried solutions from similar topics:
put ListView into SingleChildScrollView
make ListView Expanded
So the problem is:
how to make this listView scrollable?
how can I set its size to max as it can take (I mean it should be between 'List of participants' and Leave button)
how can I attach this button to be always on the bottom of screen, no matter what size of screen I have?
I hope pictures help you to understand what I mean. I also add the code but it is formatted weird, so sorry about that.
Screenshoot from device with above problem:
How it looks on another device and how it should look:
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: const Text('Flutter SDK'),
centerTitle: true),
body: Padding(
padding: const EdgeInsets.all(16),
child: !isInitializedList
? Column(
children: [
TextField(
controller: usernameController,
readOnly: true),
const SizedBox(height: 12),
TextField(
decoration: const InputDecoration(hintText: 'Conference name'),
controller: conferenceNameController),
const SizedBox(height: 12),
ElevatedButton(
onPressed: () async {
// Step 5: Call joinConference()
await joinConference();
},
child: isJoining
? const Text('Joining...')
: const Text('Join the conference')),
const Divider(thickness: 2),
const Text("Join the conference to see the list of participants.")
],
)
: Column(
children: [
Text(
'Conference name: ${conferenceNameController.text}',
style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 16)),
const SizedBox(height: 16),
Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text(
'List of participants:',
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w600))),
const SizedBox(height: 16),
// Step 7: Display the list of participants
ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return const SizedBox(height: 5);
},
shrinkWrap: true,
itemCount: participants.length,
itemBuilder: (context, index) {
var participant = participants[index];
return Padding(
padding: const EdgeInsets.all(4),
child: Row(children: [
Expanded(
flex: 1,
child: SizedBox(
height: 150,
width: 150,
child: VideoView.withMediaStream(
participant: participant,
mediaStream: participant.streams?.firstWhereOrNull((s) =>
s.type == MediaStreamType.camera),
key: ValueKey('video_view_tile_${participant.id}'))),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
"${participant.info?.name.toString()}"),
Text(
"status: ${participant.status?.name}")
]),
),
)
]),
);
}),
]),
const SizedBox(height: 16),
ElevatedButton(
style: ElevatedButton.styleFrom(primary: Colors.red),
onPressed: () async {
// Step 6: Call leaveConference()
await leaveConference();
},
child: isJoining
? const Text('Leaving...')
: const Text('Leave the conference'))
])
)
);
}
When you want to make list view expand as much as available, you need to wrap it with Expanded widget, by that you tell to column give it space as much as you have, also you need to do this for inside column agin, like this:
Column(
children: [
Text('Conference name: ${conferenceNameController.text}',
style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 16)),
const SizedBox(height: 16),
Expanded(// <--- add this
child: Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text('List of participants:',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w600))),
const SizedBox(height: 16),
Expanded( // <--- add this
child: ListView.separated(
separatorBuilder:
...
)
You can make listview scrollable with shrinkwrap parameter inside Listview.builder()

Flutter: How to Split text into 2 lines

I'm using columns to display 2 texts. 1st text represents the title and 2nd text displays the quotation. I'm trying to split the quotation text into multi-lines using the max line's property, but the text is overlapping with other items. I try to use Expanded and flexible property to overcome this issue but still, I didn't get desired output. This is what I'm trying to do:
Container(
color: Color(0xff1D1D1D),
width: double.maxFinite,
height: responsivness.safeBlockVertical! * 54.55,
// Stories Title
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Stories",
style: Theme.of(context).textTheme.headline1!),
),
// list of Stories
Expanded(
child: ListView.builder(
itemCount: 5,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
clipBehavior: Clip.none,
children: [
Padding(
padding: EdgeInsets.all(h * .014),
child: Container(
width:
responsivness.safeBlockHorizontal! *
47,
height:
responsivness.safeBlockVertical! *
17,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10),
color: Colors.amber,
),
),
),
Positioned(
top: h * .19,
left: h * .016,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Steve H.",
style: Theme.of(context)
.textTheme
.headline1!,
),
Text(
"I bet away my house and all the money i got",
style: Theme.of(context)
.textTheme
.bodyText2!,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
);
},
),
),
],
),
),
Try below code hope its helpful to you. I think the problem comes from Stack widget so remove your Stack and Positioned Widget, and used Column() widget instead.
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Stories",
style: Theme.of(context).textTheme.headline1!),
),
// list of Stories
Expanded(
child: ListView.builder(
itemCount: 5,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.amber,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Steve H.",
),
Text(
"I bet away my house and all the money i got",
style: Theme.of(context).textTheme.bodyText2!,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
);
},
),
),
],
),
),
Your result screen->
Your text is overlapping because of the Stack widget. You can either wrap your text inside a sized box to give a fix width or you can remove Stack widget and use Column instead. I dont find any particular use of stack here, so probably you can remove it without any issues.
Try wrapping with container and specify any width
Container(
width: 100,
child: Text(
"I bet away my house and all the money i got",
style: Theme.of(context).textTheme.subtitle1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Try wrapping your overlapping Text with a fixed width SizedBox, and see if it fixes your issue.
Have you tried wrapping the Text in a FittedBox()

How to design below card in Flutter

I need to design a card having an address whose size is unknown(as shown in bottom middle). The card need to grow according to the size of that address. The alignments should as shown in the image.
I tried Wrap, Flexible, ListView and some other ways but none of them worked.
You can fix the width in a container, and the height will be automatically adjusted based on the child size.
Center(
child: Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
width: 100,
child: Text('your text here...'),
),
),
),
),
You can add more widgets by using columns and rows, make sure that the mainAxisSize of your column is MainAxisSize.min. This will ensure that the column will try to minimize the height it takes..
Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
width: 100,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Industry',
style: TextStyle(fontWeight: FontWeight.bold),
),
Text('your text here...'),
],
),
),
),
),

Auto expanding Container in flutter -- for all devices

I need a Container with some text in to auto expand. I have an API call, which can be anything from 5 words to 500 words. I don't want to just have 1 fixed size that's huge, but contains 10 words.
I have tried Expanded() and SizedBox.Expand(), but I might be using them wrong
Card(
elevation: defaultTargetPlatform ==
TargetPlatform.android ? 5.0 : 0.0,
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(2.0),
decoration: BoxDecoration(color: Colors.black),
width: _screenSize.width,
height: 250,
child: Column(
children: <Widget>[
Container(
color: Colors.black,
width: _screenSize.width,
height: 35,
child: Padding(
padding: const EdgeInsets.only(
left: 15, top: 11),
child: Text("Title".toUpperCase(),
style: TextStyle(
color: Colors.white
),
),
),
),
Container(
color: Colors.white,
width: _screenSize.width,
height: 210,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 5),
child: Text("Title of expanding text", style: TextStyle(
fontSize: 25,
),
),
),
Text("Expanding text", style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.w800
),),
],
),
),
],
),
),
],
),
),
I just need the Container to expand, but stay small/get bigger
Have you tried not specifying height at all? The Container should wrap according to the child in this case.
Otherwise, the widget has a child but no height, no width, no
constraints, and no alignment, and the Container passes the
constraints from the parent to the child and sizes itself to match the
child.
Above is an extract from the official flutter documentation for Container.
Here is the official flutter documentation link.
You can use FittedBox, this will resize your text according to available area.
You can use it like this :
FittedBox(child: Text('...............Your text...............'));
I would suggest you to use Constraints...this will set Container height according to the Text child's requirement. Please see the example...
Container(
constraints: BoxConstraints(
maxHeight: double.infinity,
),
child: Column(
children: [
Text(
'Hello flutter...i like flutter...i like google...',
softWrap: true,
style: TextStyle(
color: Colors.white, fontSize: 20 , ),
),],),)
we just neeed to add mainAxisSize: MainAxisSize.min, properties inside child Column or Row where the child is set to Container
for example
AnythingYourWidget(
child: Container(
child: Column( // For Example Column
mainAxisSize: MainAxisSize.min, // these properties following the children content height available.
children: [
// YourWidget
]
)
)
),
I too had a container with a text widget inside that would not scale as the text increased in character count. Make the widget tree Container -> IntrinsicWidth -> Text/TextField and it seems to play nicely for me.
IntrinsicWidth will scale the size of the container to its child.