I have a widget containing two (text) items, one of which has variable length. I want the second item to wrap to the end of the next line if space runs out.
Flutter has a widget named Wrap which allows for wrapping content if space runs out, however I have not been able to get the desired result using all kinds of combinations of Wrap, Expanded, Row and Spacer widgets. The closest I got was the second element wrapping to the start of the second row, but I want it to go to the end of the second row.
I am fairly new to Flutter but have found ways to do it in CSS by placing the variable width element in a container and applying flex: 1 0 auto to the container and flex-wrap: wrap and flex-justify: flex-end to the flexbox containing both elements.
I tried putting the first element in an Expanded, but apparently putting an Expanded directly inside a Wrap is not allowed so that gave me errors and no results.
Put the two sentences into a list like so:
List<TextSpan> reasonList = [TextSpan(text: 'sentence1'), TextSpan(text: 'sentence2') ];
Then:
Container(
child: RichText(
text: TextSpan(
children: reasonList,
style: TextStyle(
color: Colors.black, fontSize: 16)),
),
);
This not only wraps but gives you more control over every sentence, like gesture detection and color changing.
Related
I just looking for a widget type where it provides a simple default solution to draw shared border lines between children widgets, instead of touching two different borders or turning a widget into a border. Basically it's just a table thing with the children as it's cell widgets.
There's Table in Flutter. But sadly seems like the cells is unspannable. No "colspan" thing for it's TableCell. If I put TableRows with different numbers of TableCells, I get error
Table contains irregular row lengths. Every TableRow in a Table must
have the same number of children, so that every cell is filled.
Otherwise, the table will contain holes.
I used to do it with Java.
<TableLayout ...>
<TableRow ...>
<... android:layout_span .../>
</TableRow>
</TableLayout>
I just want to do it again with Flutter. That's all.
ListView.separated might be what you are looking for
It takes the following arguments
itemBuilder for the content of your rows
separatorBuilder for creating a dynamic separator between your cells. You could use the Divider widget for that purpose.
Solved by simply put inner table inside outer table's cell.
Table(
children : [
TableRow( //This row will contains virtually spanned cell
children: [
TableCell(...),
],
),
TableRow( //This row will contains indirectly unspanned cells
children: [
TableCell(
child : Table(...),
),
],
)
]
);
And then remove outer borders for inner table leaving only inner borders.
TableBorder(
horizontalInside : BorderSide(
color : Colors.grey,
),
verticalInside : BorderSide(
color : Colors.grey,
),
)
I don't know whether it's a workaround or just how Flutter deal with it because I got the answer from Flutter's github
I have a column with 2 children. The first child has a fixed height, and the second child has dynamic content.
I want the first child to be at the head of the screen, and the second child to be in the vertical middle.
So i added an empty third child and made the first and third child Flexible so that they shared vertical space equally:
Column(
children: [
Flexible(
child: Column(
children: [_firstChild()],
),
),
_secondChild(),
Flexible(child: Container()),
],
)
This works when the content of the second child is short.
But if the second child gets tall, it clips the first child:
Isn't the Flexible supposed to distribute only the empty space when fit: FlexFit.loose? I tried both the fit possibilities. I've tried to put the first child inside a SizedBox and an Align
I've tried to make the third child a Spacer. Nothing has worked so far. The empty third child is taking half of the remaining vertical space.
EDIT:
When the second child's height is too much to make it vertically centered without clipping the first child, i want it to just behave like a default Column with MainAxisAlignment.start (like the first image)
What about this:
Stack(children:[
Center(child: SecondChild()),
Align(alignment: Alignment.topCenter, child: FirstChild()),
])
Let me provide an image:
I have a rectangle. I put here two elements, O1 and TEXT (with TextAlign.center).
For now I'm using stack, so in rectangle I have:
text in container, expanded on whole width with TextAlign.Center
Small rectangle on right (O1) on screen. (positioned widget with left: 0)
All works fine but, in some cases, If text is long, text overlap O1 - it's a problem.
How to assure a minimum left starting position for text which will work on long text (text which want to overlap O1)? i.e if text want to overlap O1, then move text to right. (O1 width = 16)
What I tried?
Add left margin / padding to container of text.
It works fine for long text which wants to overlap O1. But It does not work properly on smaller text. Because TextAlign.center applies after text to right. So this text does not looks center in the biggest rectangle, only in the smaller.
You can use the overflow in Text Widget.
new Text(
'Text largeeeeeeeeeeeeeeeeeeeeeee',
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 13.0,
fontFamily: 'Roboto',
color: new Color(0xFF212121),
fontWeight: FontWeight.bold,
),
),
Just try the methods here to see which one fits best for you. This should work if text trys to overflow over its container (into O1) it will not.
I have wanted to create the next behavior in flutter, but I can't figure out how.
Is having a text in a row with some other element, the text can have variable length. And the text space in the row should accommodate inside the row, unless the text space is larger than the remaining space in the row, then the text should use one of the text overflow options.
Here a diagram of the behavior, with the ellipsis type of text overflow:
I ave try using a combination of the row and expanded widgets, but I just can't make it.
Any suggestion?
Have you tried like this:
Row(
children: [
Flexible(
child: Text("some long text", overflow: TextOverflow.ellipsis,),
),
RaisedButton(
child: Text("Button"),
)
],
)
Using Flutter v1.20.2
The following code
var data = [
['a', 'VerylongstringwithnospacesVerylongstringwithnospaces'],
['abc', '123456789'],
['abcdefg', '123'],
];
Expanded(
child: Table(
border: TableBorder.all(color: Colors.red),
columnWidths: {
0: IntrinsicColumnWidth(),
1: IntrinsicColumnWidth(),
},
children: data.map<TableRow>((x) => (
TableRow(
children: <TableCell>[
TableCell(child: Container(child: Text(x[0]))),
TableCell(child: Container(color: Colors.green, child: Text(x[1]))),
],
)
)).toList(),
),
),
results in this layout
As you can see the text overflows the boundary of the table.
I have tried innumerable solutions but none have worked. It appears that the TableCell itself has a width bigger than it should have, comparing to the size of the column of the table.
The biggest problem is that the size of both columns are unknown, they could be hundreds of characters long or single letter. In case of it being bigger than the width the text should break to the next line.
Is there a way to make a fluid grid layout so that both sides resize according to the amount of content for each Column? The ideal layout would be something like this
The reason why It’s happening is that the IntrinsicColumnWidth doesn’t give TableCell parent size. Because it's trying to set the column width based on child width. At the same time, to make text wrapping on lines, you need to have the width of parent, otherwise text widget don’t know it’s limits.
What options do you have :
FixedColumnWidth
FlexColumnWidth
FractionColumnWidth
MaxColumnWidth
MinColumnWidth
(Last two widgets used max/min of other TableColumnWidth widgets.)
In your case if you know that the text in the first column never will need to be wraped in lines, you can remove IntrinsicColumnWidth as parameter of second column. If you know that long text is possible, add the maximum width by adding MinColumnWidth
dartpad example