Reputation: 141
I want to put 2 Text in one Row. I do the following:
Row(crossAxisAlignment: CrossAxisAlignment.end, children: [
Flexible(
child: Text(text1,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left)),
Flexible(
child: Text(text2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left)),
]),
Here I have shown the result expected with overflows and actual:
None of the Text can expand more than half the total length of the Row, even if there is free space. How to implement the result I expect, despite the fact that the length of Text1 and Text2 may be different?
Upvotes: 3
Views: 1284
Reputation: 9734
You can use the length of the strings to split the area available to each one using calculated flex
values in Flexible
. The result will not always be optimal with non monospaced fonts, but somehow you have to assign how many space should the texts occupy. You could use Expanded
to fill the remaining available space, but it only works if you have a fixed width item and use Expanded
on the other one.
Try this (setting width on the Container
and red color is only for demonstration):
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final text1 = 'Text111111111111111111';
final text2 = 'Text222';
return Container(
width: 200,
color: Colors.red,
child: Row(crossAxisAlignment: CrossAxisAlignment.end, children: [
Flexible(
flex: text1.length,
child: Text(text1,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left)),
Flexible(
flex: text2.length,
child: Text(text2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left)),
]));
}
}
Upvotes: 2
Reputation: 2815
My requirement was little bit different. In my my case the first text is label which generally requires minimum length 30 and maximum length 50 in percentage. So created a method which calculates flex factor according to texts length. You can change this threshold as per you requirement.
Pair<int, int> getTextRowFlexFactor(String? text1, String? text2) {
/**
* if flex == 0 -> the child is inflexible and determines its own size
* if flex == 1 -> the amount of space the child's can occupy in the main axis is determined by dividing
* the free space (after placing the inflexible children) according to the flex factors of the flexible children.
*/
if (isNullOrEmpty(text1) && isNullOrEmpty(text2)) {
return const Pair(0, 0);
} else if (isNullOrEmpty(text1)) {
return const Pair(0, 1);
} else if (isNullOrEmpty(text2)) {
return const Pair(1, 0);
}
const minText1LengthPercent = 30;
const maxText1LengthPercent = 50;
final text1Length = text1!.length;
final text2Length = text2!.length;
final text1LengthPercent = ((text1Length / text2Length) * 100).toInt();
// when text1LengthPercent < minText1LengthPercent,
// make text1 widget inflexible and other one flexible
if (text1LengthPercent < minText1LengthPercent) {
return const Pair(0, 1);
}
// when text1LengthPercent > maxText1LengthPercent,
// make text1 widget flexible and other one inflexible
else if (text1LengthPercent > maxText1LengthPercent) {
return const Pair(1, 0);
}
return const Pair(1, 1);
}
final textRowFlexFactor = getTextRowFlexFactor(text1, text2);
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
flex: textRowFlexFactor.left,
child:Text(
text1,
maxLines: 1,
overflow: TextOverflow.ellipsis,
)),
Flexible(
flex: textRowFlexFactor.right,
child: Text(
text2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
)),
],
);
To know more about the flex property -> https://api.flutter.dev/flutter/widgets/Flexible/flex.html
Upvotes: 0
Reputation: 11
mainAxisAlignment: MainAxisAlignment.spaceBetween,
add MainAxisAlignment.spaceBetween for row it will put space between the text aligning them to left and right.
Upvotes: 0