26

I've tried many configurations of the Flutter TextField but can't figure out how to build this one.

I'm looking for a textfield that is a single line initially and it auto expands as the text is entered into it and then at some point begins scrolling itself.

This can be achieved partially by using the maxLines: null attribute. But then when a lot of text is entered the Text in the textfield itself overflows.

And if the maxLines is set to a value then the whole textfield itself gets expanded to those many lines to start off with rather than beginning with a single line.

Is there a way to limit the height of textfield at some point like done in many chat apps like WhatsApp and telegram.

Dharman
  • 30,962
  • 25
  • 85
  • 135
sujay_br
  • 565
  • 2
  • 7
  • 16

4 Answers4

57
Container(
    child: new ConstrainedBox(
        constraints: BoxConstraints(
            maxHeight: 300.0,
        ),
        child: TextField(
                    maxLines: null,
                ),
            ),
        ),
    ),
)

In older Flutter versions it was

Container(
    child: new ConstrainedBox(
        constraints: BoxConstraints(
            maxHeight: 300.0,
        ),
        child: new Scrollbar(
            child: new SingleChildScrollView(
                scrollDirection: Axis.vertical,
                reverse: true,
                child: new TextField(
                    maxLines: null,
                ),
            ),
        ),
    ),
)
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
47

Now we actually have minLines parameter of TextField, no workaround needed anymore.

TextField(
    minLines: 1,
    maxLines: 5,
)
flomaster
  • 1,563
  • 16
  • 16
  • this should be accepted answer works well in all situations even if the direct child of the constrained box is not a text field. The accepted answer can cause some problems if direct child is not a text field. – tensor Jun 29 '20 at 07:24
  • This works, but it does not show a scrollbar on the text field when it is scrolled, which can be confusing. – Luke Hutchison Mar 11 '23 at 05:19
  • Another "gotcha" is if the user has their font size preferences to a large font, you might cause an overflow. The lines are based on font size no? – IcyIcicle Jun 08 '23 at 00:05
15

The accepted answer by Gunter is good enough if you don't have any style for the TextField. But if you have at least an underline / bottom border for the TextField, it will disappear when scroll up.

My recommendation is to calculating the lines with TextPainter, then apply the calculated number of lines to TextField. Here's the code, replace your current TextField with LayoutBuilder :

LayoutBuilder(
    builder: (context, size){
      TextSpan text = new TextSpan(
        text: yourTextController.text,
        style: yourTextStyle,
      );

      TextPainter tp = new TextPainter(
          text: text,
          textDirection: TextDirection.ltr,
          textAlign: TextAlign.left,
      );
      tp.layout(maxWidth: size.maxWidth);

      int lines = (tp.size.height / tp.preferredLineHeight).ceil();
      int maxLines = 10;

      return TextField(
        controller: yourTextController,
        maxLines: lines < maxLines ? null : maxLines,
        style: yourTextStyle,
      );
    }
  )
Bobby Stenly
  • 1,260
  • 3
  • 13
  • 23
2
TextField(
     minLines: 1,
     maxLines: 5,
     maxLengthEnforced: true,
),
Ravindra S. Patil
  • 11,757
  • 3
  • 13
  • 40
Bijoya_Banik
  • 387
  • 4
  • 12