rulila52
rulila52

Reputation: 141

Flutter right overflow two texts in row

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:

image

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

Answers (3)

Peter Koltai
Peter Koltai

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

Shahbaz Hashmi
Shahbaz Hashmi

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

Sa9
Sa9

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

Related Questions