How can stretch height of one of child widget according to another widget in a row? - flutter

I wanted to get same dynamic height of right widget to left widget in Row Widget.Below I was attaching screenshot of my expected design. Could you help how can do that.
We can see right side date widget is expanding , So I wanted to get the height of left side widget(blue and purple) same as right side widget.
If left side image widget is not possible to expand the height then is any there any possible to create custom widget, Any solution is welcome.
Thanks in advance.
Row(
children: [
Align(
alignment: Alignment.topCenter,
child: Container(
constraints: BoxConstraints(
minHeight: 40.0,
maxHeight: 50.0,
/*maxWidth: 10,
minWidth: 10,*/
),
padding: EdgeInsets.only(top: 0.0),
//height: 98,
width: 20,
child: ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(
colors: [Color(0xff12229F), Color(0xff615FDF)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
).createShader(bounds);
},
child: ImageIcon(
AssetImage('assets/images/reservations/small_timeline.png'),
color: Colors.white,
size: 40,
),
),
),
),
Expanded(
child: Column(
children: [
pickup(data),
dropoff(data),
],
),
),
],
),
After Using IntrinsicHeight
I was unable to remove default padding around the icons
IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.only(top: 0,bottom: 0),
child: Row(
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 4),
child: Icon(
Icons.fiber_manual_record,
size: 18,
color: Color(0xff11219E),),
),
Flexible(
child: Container(
decoration: BoxDecoration(
gradient:
LinearGradient(colors: [Color(0xff11219E), Color(0xff6F6AEB)]),
),
width: 4,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Icon(
Icons.fiber_manual_record,
size: 18,
color: Color(0xff6F6AEB),),
),
],
),
Expanded(
child: Column(
children: [
pickup(data),
dropoff(data),
],
),
),
],
),
),
),

It seems to me that Expanded could be used to expand your widget to full availabe height.
Keep in mind that the Row width will distribution will also expand, since no flex parameter is provided.
You already have an Expanded on the right widget so just add the other one and provide a flex value for both of them.
Some thing like 10 for left and 90 for right should work for you :)

Related

Flutter design with timeline

I'm trying to make this drawing but I'm struggling.
I don't understand how to make the white block of information dynamic. That is to say that it automatically adapts to the size in height of the elements it contains.
I am for the moment obliged to give a defined height (here 200), I would like the size to be automatic. Moreover if I do not give a defined size my gray line on the left side disappears.
The design :
ListTile(
title : Column(
children: [
Container(
width: double.infinity,
child: Row(
children: [
Container(
width: 50,
alignment: Alignment.center,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
border: Border.all(
width: 5,
color: Colors.blue,
style: BorderStyle.solid
)
),
),
),
Text('9:00 am - 9:15 am')
],
)
),
Container(
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width : 50,
alignment: Alignment.center,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.grey,
width: 3,
height : 200 // if I remove the size it desappear
),
],
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.symmetric(vertical :10),
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
color: Colors.white,
child: Column(
children: [
Text('Titre'),
Text('Info 1'),
Text('Info 2')
],
),
),
)
],
),
),
)
],
),
),
You can try this package for timelines https://pub.dev/packages/timeline_tile.
This package also automatically Sizes your widget height and width.
And for Automatically Sizing your widgets next time, You could use Expanded widget at most places in your code.
Note: An Expanded widget must be a descendant of a Row, Column, or Flex, So Use it carefully.
I think it's much easier with this package, timelines.
TimelineTileBuilder.connected(
connectionDirection: ConnectionDirection.before,
itemCount: processes.length,
contentsBuilder: (_, index) {
//your Container/Card Content
},
indicatorBuilder: (_, index) {
if (processes[index].isCompleted) {
return DotIndicator(
color: Color(0xff66c97f),
child: Icon(
Icons.check,
color: Colors.white,
size: 12.0,
),
);
} else {
return OutlinedDotIndicator(
borderWidth: 2.5,
);
}
},
connectorBuilder: (_, index, ___) => SolidLineConnector(
color: processes[index].isCompleted ? Color(0xff66c97f) : null,
),
),
),

Text align in a box decoration

I have this box decoration used for showing the reviews but I don't know what I should use to align the text properly. This is how it looks right now:
I want the username ("La fottaria to have some space left) I used Align( Alignment(8,3)) but it doesn't change the position.
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return Container(
width: 200,
margin: EdgeInsets.only(
top: 8, bottom: 8, right: 12),
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 2,
spreadRadius: 1)
], borderRadius: BorderRadius.circular(4)),
child: Column(
children: [
Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data.documents[index]
.data["avatarUrl"]),
),
Align(
alignment: Alignment(8, 3),
child: Text(snapshot
.data
.documents[index]
.data["name"]),
)
],
),
_buildRatingStars(snapshot.data
.documents[index].data["rating"]),
Text(snapshot
.data.documents[index].data["text"])
],
),
);
}
);
Inside the Row widget, you can use a SizedBox with width property.
It will give some space.
Row(
children: [
CircleAvatar(
backgroundImage:
NetworkImage(snapshot.data.documents[index].data["avatarUrl"]),
),
//insert here
SizedBox(
width: 20.0,
),
Align(
alignment: Alignment(8, 3),
child: Text(snapshot.data.documents[index].data["name"]),
)
],
)
You can remove the Align widget if you want.
Instead of align widget, I suggest you to use Container widget like this:
Container(
margin: const EdgeInsets.only(left: 15),
child: Text(snapshot
.data
.documents[index]
.data["name"]),
)
Use Align
Example:
DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 1,
),
borderRadius: BorderRadius.circular(4),
),
child: Align(
alignment: Alignment.center, // align type
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 15),
child: Text(
title,
style: TextStyle(fontSize: 17, color: Colors.blue),
),
),
),
)
You can use some inbuilt property of rows i.e Main Axis Alignment and Cross Axis Alignment to align its children.For eg:
Row(
mainAxisAligment:MainAxisAlignment.spaceEvenly,
crossAxisAligment:CrossAxisAligment.center,
children: [
CircleAvatar(
backgroundImage:
NetworkImage(snapshot.data.documents[index].data["avatarUrl"]),
),
SizedBox(
width: 20.0,
),
Text(snapshot.data.documents[index].data["name"]),
],
)
You can wrap the text widget inside padding widget also to align according to your needs.

Make container grow to fit width of sibling in column

I have two Container widgets in a Column, each containing a Text widget. I want the Container with the shortest text to expand to match the width of the other container containing the longer text. The container with the longer text should wrap the Text widget and its padding.
I can't get it to work without resorting to fixed widths on the containers:
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('short'),
)
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Container(
alignment: Alignment.center,
width: 50, // I don't want this fixed width
decoration: BoxDecoration(color: Colors.orange, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(4), bottomRight: Radius.circular(4))),
child: Padding(
padding: const EdgeInsets.fromLTRB(8,4,8,4),
child: Text('long text here'),
)
),
]
);
I've tried a couple of ways to solve it involving Expanded and Flexible, but they all result in the "red screen of death" (or at least "annoyance").
EDIT
Just to be clear - I want the Column to just wrap its content, i.e. adjust its width to the width of the containers. In summary - everything should be as narrow as possible, except for the container with the shortest text, which should instead be as wide as its sibling (the container with the longer text).
I saw your Fiddle on a comment. And what you need is IntrinsicWidth.
IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// This container has a shorter text than its sibling, so it should expand
// its width to match its sibling/parent
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'short',
textAlign: TextAlign.center,
),
),
),
),
// This container has a longer text, so it should decide the width of the
// other container (and of the parent Column)
Padding(
padding: const EdgeInsets.symmetric(vertical: 1.0),
child: Container(
color: Colors.orange,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Text(
'long text here',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
You can use something like this to take the entire width of the Widget (make sure to be inside a MaterialApp and a Scaffold/Material child (home):
Wrap(
children: <Widget>[
Container(
color: Colors.red,
child: IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
color: Colors.black,
height: 200,
child: Align(
alignment: Alignment.bottomRight,
child: Text(
"Hello World",
style: TextStyle(color: Colors.white),
),
),
),
Container(
color: Colors.blue,
height: 100,
child: Align(
alignment: Alignment.topRight,
child: Text(
"Bottom Text Longer Text",
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
),
],
)
The Align is not necessary, is just to showcase how the width actually works with "double.infinity" and moving a text to the bottom right or top right portion of it.

can't wrap my long text inside a card in flutter

I'm trying to put a text inside a card and make the card a bit flexible whenever there is a long text it goes to the next line automatically and the card gets langer
Widget ServiceCard (BuildContext context,double price){
return Container(
height: 100,
margin: EdgeInsets.only(top: 12,right: 8,left: 8),
width: MediaQuery.of(context).size.width,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)
),
color: Colors.white,
elevation: 8,
child: Stack(
children: <Widget>[
Positioned(
top: 8,
left: 8,
child: Text("\$$price"),
),
Positioned(
right: 8,
top: 8,
child: Container(
// height: 70,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
alignment: Alignment.topRight,
child: Text("غسيل شعر",style: TextStyle(fontSize: 16),)
),
Opacity(
opacity:0.7,
child: Text(
"يتم تصفيف الشعر وغسيل يتم تصفيف الشعر وغسيل يتم تصفيف الشعر وغسيل"
)
),
],
),
),
)
],
),
),
);
}
with this code im having the text goes over the card and not going to the next line and even the card is in a constent heghit not wrapped
To make Text wrap on overflow, ideally it has to be sized to full width and maxLines property must be set to null.
However, I can see that you have encountered an "edge-case" - all your text is placed in a Stack widget, which does not fit its children in width by default.
To solve this, change your Positioned(...) widget to Positioned.fill.
e.g.
Positioned.fill(
right: 8,
top: 8,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // You might want to use this, too - this stretches all children in width by default
children: <Widget>[
Container(
alignment: Alignment.topRight,
child: Text("غسيل شعر", style: TextStyle(fontSize: 16))
),
Opacity(
opacity: 0.7,
child: Text(
"يتم تصفيف الشعر وغسيل يتم تصفيف الشعر وغسيل يتم تصفيف الشعر وغسيل",
textDirection: TextDirection.rtl, // I assume this would be helpful too, if your language reads from right to left.
)
),
],
),
),
)
Let me know if this helped.

Expand widgets inside the Stack widget

I have a stack widgets with two widgets inside.
One of them draws the background, the other one draws on top of that.
I want both widgets to have the same size.
I want the top widget, which is a column, to expand and fill the stack vertically to the size that is set by the background widget.
I tried setting the MainAxis mainAxisSize: MainAxisSize.max but it didn't work.
How can I make it work?
Use Positioned.fill
Stack(
children: [
Positioned.fill(
child: Column(
children: [
//...
],
),
),
//...
],
);
More info about Positioned in Flutter Widget of the Week
How does it work?
This is all about constraints. Constraints are min/max width/height values that are passed from the parent to its children. In the case of Stack. The constraints it passes to its children state that they can size themselves as small as they want, which in the case of some widgets means they will be their "natural" size. After being sized, Stack will place its children in the top left corner.
Positioned.fill gets the same constraints from Stack but passes different constraints to its child, stating the it (the child) must be of exact size (which meant to fill the Stack).
Positioned.fill() is the same as:
Positioned(
top: 0,
right: 0,
left: 0,
bottom:0,
child: //...
)
For even more examples and info: How to fill a Stack widget and why? and Understanding constraints.
You can try wrapping the Column with a positioned widget. Set top to 0 and bottom to 0. This will make the column fill the stack vertically.
sample code:
Stack(
children: <Widget>[
// Background widget rep
Container(
color: Colors.pink,
),
Positioned(
top: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('madonna'),
Text('flutter'),
],
),
)
],
)
I think you could wrap you column in a container like this:
Container(
height: double.infinity,
width: double.infinity,
child: Column()
),
The accepted answer did not answer my issue completely. So, I put my code here in case you have a similar issue.
class NoContentView extends StatelessWidget {
const NoContentView({Key? key, required this.message}) : super(key: key);
final String message;
#override
Widget build(BuildContext context) {
return Expanded(
child: Stack(
children: [
Positioned.fill(
child: FittedBox(
child: const Image(image: AssetImage(AppImages.noReceiptsWeb), fit: BoxFit.fitWidth),
),
),
MessageView(message: message),
],
),
);
}
}
In my case, I thought that I needed to expand the container in the light blue color with an expanded widget inside the stack widget.
Problems arose, especially since I was adding the stack widget in the column widget, and the way to make the container double.infinity dimensions I definitely had a problem with the vertical axis.
In the end, I managed to show it like this photo...
Column(
children: [
//filter
Container(
color: orange,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Text(
'All',
style: getRegular(color: white.withOpacity(.6)),
),
),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 10, 0),
child: Text(
'Ready',
style: getRegular(color: white.withOpacity(.6)),
),
),
freeh(),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
],
),
Row(
children: [
Icon(
filter,
color: white.withOpacity(.7),
size: 20,
),
Text(
'FILTER',
style: getLight(
color: white.withOpacity(.7),
),
),
freeh(),
],
),
],
),
),
Expanded(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
color: lightBlue, //here to use map>>>>
),
Container(
height: 35,
width: 120,
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
FontAwesomeIcons.listUl,
color: white.withOpacity(.8),
size: 20,
),
Text(
'List View',
style: getRegular(color: white.withOpacity(.8)),
)
],
),
),
],
),
)
],
),