Magnus
Magnus

Reputation: 18800

Make Text widget shrink to longest line when text is wrapped to multiple lines

Is it possible to shrink a Text widget to the width of the longest line when the text is wrapped because it becomes too long to fit on a single line?

Basically I have this custom widget:

class MyWidget extends StatelessWidget {
  final String text1;
  final String text2;

  const MyWidget({Key? key, this.text1='', this.text2=''}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,              
      children: [
        Expanded(
          child: Container(
            color: Colors.lightBlue,
            child: Center(child: Text(text1))
          )
        ),
        Expanded(
          child: Container(
            color: Colors.lightGreen,
            alignment: Alignment.centerRight,
            child: Text(text2, textAlign: TextAlign.start)
          )
        )
      ]
    );
  }
}

Here's what it looks like with one short and one long text:

enter image description here

But what I want is this:

enter image description here

Note that I do not want the text to be right-aligned - the wrapped lines should be aligned to the left, but the entire Text widget should shrink to the longest line.

Upvotes: 2

Views: 1011

Answers (3)

Esmaeil Ahmadipour
Esmaeil Ahmadipour

Reputation: 1192

This answered for me. You can replace the following part in your code:

     Expanded(
      child: Container(
          color: Colors.lightGreen,
          alignment: Alignment.centerRight,
          child: LayoutBuilder(builder: (context, size) {
            final span = TextSpan(text: text2);
            final tp = TextPainter(
                text: span,
                maxLines: 1,
                textDirection: Directionality.of(context));
            tp.layout(maxWidth: size.maxWidth);
            if (tp.didExceedMaxLines) {
              return Padding(
                padding: const EdgeInsetsDirectional.only(start: 16.0),
                child: Text(text2),
              );
            } else {
              return Text(text2);
            }
          })))

Upvotes: 0

Magnus
Magnus

Reputation: 18800

Just found the answer myself when investigating the more exotic properties of the Text widget. Apparently, textWidthBasis: TextWidthBasis.longestLine does exactly what I want.

class MyWidget extends StatelessWidget {
  final String text1;
  final String text2;

  const MyWidget({Key? key, this.text1='', this.text2=''}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,              
      children: [
        Expanded(
          child: Container(
            color: Colors.lightBlue,
            child: Center(child: Text(text1))
          )
        ),
        Expanded(
          child: Container(
            color: Colors.lightGreen,
            alignment: Alignment.centerRight,
            child: Text(text2, textWidthBasis: TextWidthBasis.longestLine)
          )
        )
      ]
    );
  }
}

Upvotes: 6

Noha El Sheweikh
Noha El Sheweikh

Reputation: 164

you can wrap Text with FittedBox

FittedBox(
           fit: BoxFit.fitWidth,
           child: Text(
           "some text"
            ),),

Upvotes: 0

Related Questions