323

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.

19 Answers 19

562

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.

Sign up to request clarification or add additional context in comments.

6 Comments

The catch is to have maxLines: null. Without hi it doesn't seem to work
If you want it to look more thicker like <textarea> in HTML, use minLines: 4
What if I want to give input for maximum line 5?
The text wraps nicely now but no longer submits on Enter. It just goes to a new line in the text field. Am I missing something? I'm on an android simulator.
@Barry Can you clarify? As far as I know you can definitely assign null to properties with null safety!
|
126

If you want your TextField be adapted 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 you can 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 that's why we should set it to some value.

2 Comments

I have corrected the widget name from: TextInputField, to: TextField. In flutter there is not TextInputField, just TextField or TextFormField. Unless you create one with custom name.
In your example, its default showing 5 lines. I want to saw 1 line only. If you want to add more data then he/she can press enter.
48

1. Fixed height:

enter image description here

(A) Based on lines:

TextField(
  minLines: 3, // Set this
  maxLines: 6, // and this
  keyboardType: TextInputType.multiline,
)

(B) Based on height:

SizedBox(
  height: 200, //     <-- TextField expands to this height. 
  child: TextField(
    maxLines: null, // Set this 
    expands: true, // and this
    keyboardType: TextInputType.multiline,
  ),
)

2. Flexible height:

Use a Column and wrap the TextField in Expanded:

Column(
  children: [
    Expanded(
      child: TextField(
        maxLines: null, // Set this 
        expands: true, // and this
        keyboardType: TextInputType.multiline,
      ),
    ),
  ],
)

(Optional) Set decoration:

You can se this decoration to any of the above TextField:

decoration: InputDecoration(
  hintText: 'Write a message',
  filled: true,
)

1 Comment

expands: true saves my day.
27

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,
  )

2 Comments

Consider adding how you actually use _inputHeight to set the height of the input
As TextField can wrap the line without spliting the line with '\n' count would fail. So I'm counting text lines with this code: int count = (_textEditingController.text.length / (MediaQuery.of(context).size.width * 0.06) ).round() ;
24

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).

1 Comment

textInputAction: TextInputAction.newline, - was looking for this, it makes enter input new line, thank
19

You have to use this line in the TextField widget :

maxLines: null,

if didn't work , just note that you have to delete this :

textInputAction: TextInputAction.next

it's disabling multi line property action in the keyboard ..

Comments

18
   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)),
                    ),
                  ),
                ),

Comments

8

use this

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

Comments

8

This Code Worked for me, Also I'm able to use ENTER for web & mobile.

@override
  Widget build(BuildContext context) {
      double width = MediaQuery.of(context).size.width;
      double height = MediaQuery.of(context).size.height;
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start, 
      children: [
      Container(
        child: ConstrainedBox(
          //  fit: FlexFit.loose,
          constraints:  BoxConstraints(
            maxHeight: height,//when it reach the max it will use scroll
            maxWidth: width,
          ),
          child: const TextField(
            keyboardType: TextInputType.multiline,
            maxLines: null,
            minLines: 1,
            decoration: InputDecoration(
              fillColor: Colors.blueAccent,
              filled: true,
              hintText: "Type  ",
              border: InputBorder.none,
            ),
          ),
        ),
      )
    ]);
  }

enter image description here

Comments

6

Use Expanded widget for dynamic feels

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

Comments

6

TextField has maxLines property.

enter image description here

4 Comments

I know that. While it wraps the content, you still can't press enter to manually create a new line. At least on android, because you don't have access to the enter button.
Ah, I missed that issue. I saw a similar issue dating from 2016, so I assumed it was solved. Quite sad we still can't do it.
It looks like this is now fixed (github.com/flutter/flutter/issues/8028). I tried multi-line on both iOS and Android and both can now create new lines in the text field.
It can actually create a new line now, but must to press the enter key twice !
4

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

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

Comments

3

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

textInputAction: TextInputAction.newline,

Comments

3

For autowrap just use null for maxLines

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

or

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

Comments

3

use this

 Expanded(
        child: TextField(
          controller: textMessageController,
          keyboardType: TextInputType.multiline,
          textCapitalization: TextCapitalization.sentences,
          minLines: 1,
          maxLines: 3,
          onChanged: ((value) {
            setState(() {
              _messageEntrer = value;
            });
          }),
          decoration: InputDecoration(
            hintText: "Type your message here",
            hintMaxLines: 1,
            contentPadding:
                const EdgeInsets.symmetric(horizontal: 8.0, vertical: 10),
            hintStyle: TextStyle(
              fontSize: 16,
            ),
            fillColor: Colors.white,
            filled: true,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(30.0),
              borderSide: const BorderSide(
                color: Colors.white,
                width: 0.2,
              ),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(30.0),
              borderSide: const BorderSide(
                color: Colors.black26,
                width: 0.2,
              ),
            ),
          ),
        ),
      ),

Comments

2

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.

Comments

0

'\n' and "\n" behave differently. It's important to note the difference between " and '

Comments

0

I don't see how to address the vertical alignment of the label in any answer. When you follow any of the accepted approaches (using minLines or SizedBox), you'll see that the label is vertically aligned to the center of the input, when you type some text into the input, those text will also be vertically aligned to the center. This is not necessarily what most people expected. Here is how to align both of them to the top.

The 2 important attributes are alignLabelWithHint: true and textAlignVertical: const TextAlignVertical(y: -1)

TextFormField(
  decoration: const InputDecoration(
    labelText: 'My input',
    alignLabelWithHint: true,  // This align the label to the top
  ),
  keyboardType: TextInputType.multiline,
  maxLines: null,
  minLines: 4,
  textAlignVertical: const TextAlignVertical(y: -1),  // This align the input text to the top
)

1 Comment

great job! that was helpful
-1

To create a multi-line editable text field in Flutter, you can use the TextField widget along with the maxLines parameter set to null or a value greater than 1. This allows the text field to accept multiple lines of input. Additionally, you can set the KeyboardType parameter to TextInputType.multiline to allow users to multiline text

TextField(
          controller: _controller,
          keyboardType: TextInputType.multiline,
          maxLines: null, // Allows for unlimited lines
          decoration: InputDecoration(
            hintText: 'Enter your text here',
            border: OutlineInputBorder(),
          ),
        ),

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.