Flutter resize image to fill available space - flutter

I would like to have this image fill the available space between the top element and the bottom element. Also I would like the bottom text to be always at the bottom.
This is how I implemented it right now:
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(children: topWidgets),
Container(
color: Colors.red,
child: Column(children: [
Image.asset("assets/empty_state/illustration_01.png", height: 200),
Text("No matches so far")
]),
)
]
)
I have tried to use the fit property of the Image without luck. If I don't use height: 200 I wouldn't be able to see the bottom text because it would go out of the screen (at the bottom)
I don't know if having a Column wrapping text and image is a good approach but I think it is the best among the ones I tried so far.

Container(
height: MediaQuery.of(context).size.height, //for max height
width: MediaQuery.of(context).size.width,//for max width
child: Column(
children: [
Expanded(
flex: 1, // flex is used to expand less/more the contained widget
child: topWidgets),
Expanded(
flex: 3,
child: Container( //for red background
color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
flex: 3, //increase to fill more space of picture
child: FittedBox(
fit: BoxFit.fill, // the picture will acquire all of the parent space.
child: Image.asset("assets/empty_state/illustration_01.png"),
)),
Expanded(
flex: 1, //by default flex is 1. so don't do this and save a line
child: Text("No matches so far"),)
],
),
))
],
),
)

Related

Flutter - How to stretch Column inside Row to maximum available height?

I need create this UI in my flutter app:
It is row for my list. This is my code:
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
CachedNetworkImage(
imageUrl: photoUrl,
imageBuilder: (context, imageProvider) => Container(
height: 112,
width: 90,
),
),
const SizedBox(
width: 14,
),
Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${title}',
),
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: descriptionWidth,
child: Text(
'${shortDescription}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
),
Text(
'${footer}',
),
],
)
],
);
I need the test block to occupy a height equal to the image. but when the text is all in the middle, it takes up a lot less height. this is an example of how my code works now:
how do I fix this? How to stretch Column inside Row to maximum available height?
I tried several options but then it breaks the display of multi-line text.
While height is fixed, you can wrap Column with SizedBox(height:112) and to control textOverflow, wrap SizedBox with Expanded.
Expanded(
child: SizedBox(
height: 112,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Full method
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
/// replace with image
height: 112,
width: 90,
color: Colors.red,
),
const SizedBox(
width: 14,
),
Expanded(
child: SizedBox(
height: 112,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${title}',
),
Flexible(
child: Text(
'${shortDescription}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Text(
'${footer}',
),
],
),
),
)
],
);
For Maximum Height You can use
Expanded(
child : --- your child widget
)
or
Flexible(
child: -- your child widget
)
A widget that expands a child of a Row, Column, or Flex so that the child fills the available space.
Using an Expanded widget makes a child of a Row, Column, or Flex expand to fill the available space along the main axis (e.g., horizontally for a Row or vertically for a Column). If multiple children are expanded, the available space is divided among them according to the flex factor.
An Expanded widget must be a descendant of a Row, Column, or Flex, and the path from the Expanded widget to its enclosing Row, Column, or Flex must contain only StatelessWidgets or StatefulWidgets (not other kinds of widgets, like RenderObjectWidgets).
First of all, you need to fixed the card height for better positioning of your text with the card image and then expand your column to dynamically handle the multiline of text. ANd you don't need to use the align widget
try the below code
Container(
height: 112, // here you fixed the container height
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
CachedNetworkImage(
imageUrl:
"https://avatars.githubusercontent.com/u/26745548?v=4",
imageBuilder: (context, imageProvider) => Container(
height: 112,
width: 90,
),
),
const SizedBox(
width: 14,
),
Expanded(
// here expand your column
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'title',
),
Text(
'{shortDescription 23487509387 2039487502930349857 03984 5 30498 503498 503948 70293847 50923487503}',
),
Text(
'footer',
),
],
),
)
],
),
)
output:

Expand Container to fill remaining space in Column

I have a problem with building a specific layout in flutter.
What I need is:
Scrollable screen, with two columns, where the first col is of certian (but dynamic) height. And the second col has part of certain (but dynamic) height and the rest of the col I want to fill remaining space.
The code structure.
Row(
children: [
Expanded(
child: Column(children:[
someDynamicHeightWidgetsHere()])),
Expanded(child: Column(children: [
someWidgetsHere(),
here fill remainind space to match the first column]))
]
)
Use IntrinsicHeight, This widget only expands to its child height.
This class is useful, for example, when unlimited height is available and
you would like a child that would otherwise attempt to expand infinitely to
instead size itself to a more reasonable height.
Example:
IntrinsicHeight(
child: Row(
children: [
Expanded(
child: Column(
children: [
Container(
height: 800,
color: Colors.blue,
),
],
),
),
Expanded(
child: Column(
children: [
Container(
height: 400,
color: Colors.red,
),
Expanded(
child: Container(
color: Colors.yellow,
),
),
],
),
),
],
),
Output:

Flutter align widget horizontaly and verticaly

I am working on a Flutter project. I'm trying to create a widget like the image below and I can't manage to do it.
So what I'm trying to do, is to create a widget with a Text at the top left (the size of this widget is not constant and depends on the text in it).
I'm trying to align 2 other widgets with the Text:
The Widget 1 is aligned horizontaly and centered with the Text widget and at its right with no space between
The Widget 2's right edge is aligned verticaly with the Text widget's right edge, and is positioned under it (and there is no space between the 2 widgets).
I tried to implement this with Column and Row widgets or with a GridView but I couldn't manage to do so.
Also the overall size of this custom widget has to be shrinked.
Does someone know how to do something like that ?
Thank you.
This works
Container(
width: double.infinity,
height: 300,
color: Colors.grey[200],
child: Column(
children: <Widget>[
Row(
children: [
Flexible(
flex: 2,
child: Container(
height: 200,
color: Colors.blue,
),
),
Flexible(
flex: 1,
child: Container(
height: 100,
color: Colors.green,
),
),
],
),
Row(
children: <Widget>[
Flexible(
flex: 2,
child: Align(
alignment: Alignment.centerRight,
child: Container(
width: 150,
height: 100,
color: Colors.orange,
),
),
),
Flexible(
flex: 1,
child: Container(),
),
],
),
],
),
),

Flutter/Dart row is not centering within the remaining space

I am trying to center a group of objects within a row using Flutter/Dart. I have tried various methods and all have failed. I want the icon to be to the left of the screen and the remaining variables (trips, followers, and following) to be centered in the remaining space. I have tried it a variety of ways using the MainAxisAlignment and CrossAxisAlignment classes based on some solutions I found on SO but none have worked. What am I doing wrong?
Column(
children: <Widget>[
ClipOval(
child: Material(
color: Colors.grey, // button color
child: InkWell(
child: SizedBox(
width: 80,
height: 80,
child: Align(
alignment: Alignment.center,
child: Icon(
Icons.person,
size: 65.0,
),
),
),
),
),
)
],
),
Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
trips, followers, following,
],
),
],
),
Image 1: How it currently looks
Image 2: Flutter Inspector View
You want to evenly distribute the space right from the icon between the three texts, right?
I would solve this by wrapping the 3 widgets in another row for the rest of the space without the icon and then wrapp the Text in an expanded widget that fills the rest of the space.
i assume that trips, followers and following are columns.
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
ClipOval(
....(your stuff)
)
]
),
Row(
children: <Widget>[
Expanded(
child: trips
),
Expanded(
child: followers
),
Expanded(
child: following
),
]
)
]
) //Row End
In the Row documentation you can see how the expanded takes a third of the available space. [1]

Word-wrapping do not working with long text

Here is my widget:
return Card(
child: Container(
height: 150,
child: Row(
children: <Widget>[
Placeholder(
fallbackHeight: 100,
fallbackWidth: 100,
),
Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Flexible(
child: Text(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasssssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
overflow: TextOverflow.ellipsis,
maxLines: 4,
)),
// Expanded(flex: 8, child: Text("bbb")),
Flexible(child: Text("bbb")),
// Flexible(child: Text("aaa")),
],
),
)
],
),
));
I expected that text will be placed on new line, but I am getting overflow:
Wrap your inner Container with an Expanded to provide it with the available parent constraints, otherwise the Container has infinite height and will result in an overflow (because you are on landscape).
Expanded(
child: Container(
width: _deviceHeight,
color: Colors.red,
child: Column(
...
You could wrap the second element of the Row with Flexible, like this:
Row(
children: <Widget>[
Placeholder(..),
Flexible(
child: Container(
color: Colors.red,
child: Column(...
Inside the Row you need Placeholder to keep its width and Container width to be flexible.
Edit: And you should remove the width of the Container, since it would be flexible and it should take as much as possible to fit the screen.