Reputation: 277567
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.
Upvotes: 319
Views: 289881
Reputation: 9
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(),
),
),
Upvotes: -1
Reputation: 506
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
)
Upvotes: 0
Reputation: 917
'\n' and "\n" behave differently. It's important to note the difference between " and '
Upvotes: 0
Reputation: 1961
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 ..
Upvotes: 18
Reputation: 268314
(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,
),
)
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,
),
),
],
)
decoration
:You can se this decoration to any of the above TextField
:
decoration: InputDecoration(
hintText: 'Write a message',
filled: true,
)
Upvotes: 46
Reputation: 111
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,
),
),
),
),
),
Upvotes: 3
Reputation: 188
Use Expanded
widget for dynamic feels
Expanded(
child: TextField(
keyboardType: TextInputType.multiline,
minLines: 1,
maxLines: 3,
),
)
Upvotes: 6
Reputation: 6022
For autowrap just use null
for maxLines
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
or
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
Upvotes: 3
Reputation: 1646
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.
Upvotes: 125
Reputation: 603
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,
),
),
),
)
]);
}
Upvotes: 8
Reputation: 1518
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).
Upvotes: 23
Reputation: 665
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)),
),
),
),
Upvotes: 18
Reputation: 4008
Specify TextInputAction.newline to make a TextField respond to the enter key and accept multi-line input:
textInputAction: TextInputAction.newline,
Upvotes: 3
Reputation: 1006
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,
)
Upvotes: 27
Reputation: 8155
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.
Upvotes: 553
Reputation: 14938
if above once not worked for you then try add minLines also
TextField(
keyboardType: TextInputType.multiline,
minLines: 3,
maxLines: null);
Upvotes: 4
Reputation: 21
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.
Upvotes: 2
Reputation: 169
use this
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: //Number_of_lines(int),)
Upvotes: 8