can't wrap my long text inside a card in flutter - 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.

Related

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

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 :)

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,
),
),
),

How to use Align or Positioned in Stack , Taking into account the direction of the language

In my case, I have a Stack containing Icon and Card
I want the icon to appear in the right corner in case LTR and in the left corner in case RTL
I have the following code:
Stack(
children: <Widget>[
Card(
color: Colors.white,
elevation: 4,
margin: EdgeInsets.only(top: 8, right: 8, left: 8),
child: Container(
height: 100,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('text 1'),
Text('text 2'),
Text('text 3'),
],
),
),
),
),
Positioned(
top: 10,
left: 10,
child: Icon(
Icons.ac_unit,
size: 50,
),
)
],
);
The result in RTL mode is :
The result in LTR mode is :
How can I fix this
try this
Positioned.directional(textDirection:Directionality.of(context) ,
top: 10,
end: 10,
child: Icon(
Icons.ac_unit,
size: 50,
),
)
UPDATE
Put the icon inside a Container with maxWidth and set the alignment like below
alignment: isRTL? Alignment.centerLeft: Alignment.centerRight;
set the alignment property of Stack like this.
when the Language is changed to RTL just call
setState((){
isRTL = true;
})
in a stateful widget.
vice versa if you want to change it to LTR

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.

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.