176
votes

It may sound easy but How can we do a multi-line editable textfield in flutter? TextField works only with a single line.

Edit: some precisions because seems like it's not clear. While you can set multiline to virtually wrap the text content, it's still not multiline. It's a single line displayed into multiple lines. If you want to do something like this then you can't. Because you don't have access to ENTER button. And no enter button means no multiline.

13

13 Answers

293
votes

To use auto wrap, just set maxLines as null:

TextField(
  keyboardType: TextInputType.multiline,
  maxLines: null,
)

If the maxLines property is null, there is no limit to the number of lines, and the wrap is enabled.

51
votes

If you want that your TextField should adapt to the user input then do this:

TextField(
    keyboardType: TextInputType.multiline,
    minLines: 1,//Normal textInputField will be displayed
    maxLines: 5,// when user presses enter it will adapt to it
    );

here set the max lines to whatever you want and you are good to go. In my opinion setting the maxlines to null is not a good choice we should set it to some value.

19
votes

Although other people already mentioned that the keyboard type "TextInputType.multiline" can be used, I wanted to add my implementation of a TextField that automatically adapts its height when a new line is entered, as it is often desired to immitate the input behaviour of WhatsApp and similar apps.

I'm analyzing the number of '\n' chatacters in the input for this purpose each time the text is changed. This seems to be an overkill, but unfortunately I didn't find a better possibility to achieve this beahivour in Flutter so far and I didn't notice any performance problems even on older smartphones.

class _MyScreenState extends State<MyScreen> {
  double _inputHeight = 50;
  final TextEditingController _textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _textEditingController.addListener(_checkInputHeight);
  }

  @override
  void dispose() {
    _textEditingController.dispose();
    super.dispose();
  }

  void _checkInputHeight() async {
    int count = _textEditingController.text.split('\n').length;

    if (count == 0 && _inputHeight == 50.0) {
      return;
    }
    if (count <= 5) {  // use a maximum height of 6 rows 
    // height values can be adapted based on the font size
      var newHeight = count == 0 ? 50.0 : 28.0 + (count * 18.0);
      setState(() {
        _inputHeight = newHeight;
      });
    }
  }


  // ... build method here
  TextField(
    controller: _textEditingController,
    textInputAction: TextInputAction.newline,
    keyboardType: TextInputType.multiline,
    maxLines: null,
  )
9
votes
   TextFormField(
                  minLines: 2,
                  maxLines: 5,
                  keyboardType: TextInputType.multiline,
                  decoration: InputDecoration(
                    hintText: 'description',
                    hintStyle: TextStyle(
                      color: Colors.grey
                    ),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(20.0)),
                    ),
                  ),
                ),
7
votes

Use expands and you don't need to give minLines or maxLines any specific value:

TextField(
  maxLines: null,
  expands: true, 
  keyboardType: TextInputType.multiline,
)
7
votes

While this question is rather old, there is no extensive answer that explains how to dynamically resize the TextField with little developer effort. This is especially of major importance when the TextField is either placed in a flexbox such as ListView, SingleChildScrollView, etc. (the flexbox will not be able to determine the intrinsic size of an expandable TextField).

As suggested by many other users, build your TextField like so:

TextField(
  textInputAction: TextInputAction.newline,
  keyboardType: TextInputType.multiline,
  minLines: null,
  maxLines: null,  // If this is null, there is no limit to the number of lines, and the text container will start with enough vertical space for one line and automatically grow to accommodate additional lines as they are entered.
  expands: true,  // If set to true and wrapped in a parent widget like [Expanded] or [SizedBox], the input will expand to fill the parent.
)

How to cope with the missing intrinsic height of the TextField?

Wrap the TextField in a IntrinsicHeight class to provide the dynamically computed intrinsic height of the expandable TextField to its parent (when requested via e.g. flexbox).

6
votes

use this

TextFormField(
      keyboardType: TextInputType.multiline,
      maxLines: //Number_of_lines(int),)
5
votes
2
votes

Specify TextInputAction.newline to make a TextField respond to the enter key and accept multi-line input:

textInputAction: TextInputAction.newline,
1
votes

Official doc states: The maxLines property can be set to null to remove the restriction on the number of lines. By default, it is one, meaning this is a single-line text field.

NOTE: maxLines must not be zero.

1
votes

if above once not worked for you then try add minLines also

TextField(
        keyboardType: TextInputType.multiline,
        minLines: 3,
        maxLines: null);
0
votes

For TextFormField widget, You can set minLines and maxLines if you want to set fix number of lines. Otherwise you can also set maxLines to null.

TextFormField(
      minLines: 5,
      maxLines: 7,
      decoration: InputDecoration(
          hintText: 'Address',
          border: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
          ),
      ),
),
-1
votes

Use Expanded widget for dynamic feels

Expanded( child: TextField( keyboardType: TextInputType.multiline, minLines: 1, maxLines: 3, ), )