Related
I need of a Box where insert and store some informations that comes as user input, I'm using the 'TextField' so I changed the 'maxLines' option in my 'TextField' from default value (1) to (2) and when I want to insert some text here I can't leave the box because the 'Done' button changed to 'return' blocking me! The keyboard is blocked too.
I'm doing this because I would like a Box with some text inside (like a description) that I can move where I want and change all its properties.
My issue is that the textfield writes all in one line, I need of a newline at the border of the textfield.
Do you know how to handle the TextField better?
This is a part of the code :
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
body : Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
image: _image == null
? AssetImage('assets/images/io.png')
: FileImage(_image), // here add your image file path,
alignment: Alignment.topCenter,
),
),
child: GestureDetector(
child:Container(
alignment: Alignment.center,
child : ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 400,
maxWidth: 400,
),
child: TextField(
minLines: 1,
maxLines: 2,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
const Radius.circular(48.0)
),
),
labelText: 'Descrizione',
labelStyle: TextStyle(
backgroundColor: Colors.white,
),
),
),
),
),
)
)
);
P.S.: I'm studying this 'GestureDetector', it should be useful for this purpose I guess.
In the TextField go into InputDecoration and add a Widget to the suffix property . The suffix property is a Widget that shows at the end of the Textfield.
FocusNode node = FocusNode();
TextField(
minLines: 1,
maxLines: 2,
focusNode: node,
decoration: InputDecoration(
suffix: RaisedButton(
onPressed: () {
node.unfocus();
},
child: Text("Done"),
),
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(const Radius.circular(48.0)),
),
labelText: 'Descrizione',
labelStyle: TextStyle(
backgroundColor: Colors.white,
),
),
),
How can I remove the underline from DropdownButtonFormField (check photo below), I have tried various combinations of options with InputDecortaion couldn't find any way.
SizedBox(
width: 100.0,
child: DropdownButtonFormField<int>(
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide:
BorderSide(color: Colors.white))),
value: 2,
items: <DropdownMenuItem<int>>[
DropdownMenuItem<int>(
value: 1,
child: Text("Owner"),
),
DropdownMenuItem<int>(
value: 2,
child: Text("Member"),
),
],
),
Just wrap DropdownButton inside DropdownButtonHideUnderline like this :
new DropdownButtonHideUnderline(
child: DropdownButton()
)
Setting the underline property to SizedBox() makes it invisible too:
...
DropdownButton(
underline: SizedBox(),
...
One way of Doing it :
In your Code - change decoration: InputDecoration to decoration: InputDecoration.collapsed
body: SizedBox(
width: 100.0,
child: DropdownButtonFormField<int>(
decoration: InputDecoration.collapsed(hintText: ''),
value: 2,
...
OR
In your Code - instead of border Use enabledBorder: UnderlineInputBorder
DropdownButtonFormField<int>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white))),
value: 2,
items: <DropdownMenuItem<int>>[
....
The proper/clean solution nowadays is to use InputBorder.none:
DropdownButtonFormField<int>(
decoration: InputDecoration(
enabledBorder: InputBorder.none,
...
),
...
)
You might also want to set border, focusedBorder, errorBorder, and disabledBorder to InputBorder.none if you want to avoid the border from showing in all cases.
underline can take a widget so, you just have assigned it an empty Container, or a SizedBox.shrink()
underline:Container(),
-- or --
underline:SizedBox.shrink(),
Example :
child: DropdownButton<String>(
// Just have to assign to a empty Container
underline:Container(),
value: dropdownValue,
icon: Icon(Icons.keyboard_arrow_down),
iconSize: 24,
elevation: 16,
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items:[
deptList[0].dept,
deptList[1].dept,
deptList[2].dept,
deptList[3].dept,
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
Add underline: Container() to your settings like this:
SizedBox(
...
underline: Container(),
),
According to this [Flutter Doc] You can do like this. Simply create an object of DropdownButtonHideUnderline class and pass your current implementation of the DropdownButton as the child of DropdownButtonHideUnderline. Thts it ;)
DropdownButtonHideUnderline(
child: new DropdownButton<String>(
......
),
),
As of now, DropdownButtonFormField doesn't support DropdownButtonHideUnderline.
Although it uses it under the hood to remove the underline from DropdownButton but then applies it's own decoration on top of that
Setting border to InputBorder.none will do the job
DropdownButtonFormField<String>(
decoration: InputDecoration(border: InputBorder.none)
)
If you want the border to appear on error you can use
InputDecoration(
border: InputBorder.none,
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
),
You can change underline property to blank or null widget it will work like charm check the below property
underline: widget or SizedBox(),
Ex:-
DropdownButton(
icon: Icon(Icons.more_vert),
isExpanded: true,
value: dropValue,
underline: widget or SizedBox(),
use
DropdownButton<String>(
hint: Text("Status"),
value: 'Text Default',
isExpanded: true,
iconSize: 30,
underline: Container(
height: 1.0,
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.transparent, width: 0.0))
),
),
...
Easy Way to do it
DropdownButtonFormField<String>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
...
)
DropdownButtonHideUnderline(
child: DropdownButton(
isExpanded: true,
hint: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Select State"),
),
style: MyStyle().getTextStyle("x1black"),
items: <String>[
'Messaging',
'Chating',
'No Longer Interested',
'Document Request'
].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
Underline takes a Widget. Pass it a blank widget, like below.
DropdownButton<T>(
value: value,
underline: SizeBox(), // Empty box will remove underline
)
You could try the following code:
decoration: InputDecoration(
border: InputBorder.none,
)
To disable every border on the width, set InputBorder.none for border attribute. Or if you prefer to disable only the border when dropdown is enable, set for enabledBorder.
if DropdownButtonFormField text get trim due to outline border then use this code:
DropdownButtonFormField<String>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
isDense: true,)
DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: false,
splashColor: Colors.grey,
child: DropdownButton<String>(
value: _myPargna,
iconSize: 25,
icon: Icon(Icons.arrow_drop_down),
style:
TextStyle(fontSize: 18, color: Color(0xFF1f193d)),
hint: Row(
children: [
SizedBox(width: 11),
Text(
'Select Province',
style: TextStyle(color: Colors.grey),
),
],
),
onChanged: (String newValue) {
setState(() {
_myPargna = newValue;
});
},
items: items.map((String items) {
return DropdownMenuItem(
child: Row(
children: [
SizedBox(width: 12),
Text(
items,
style: TextStyle(color: Colors.black),
),
],
),
value: items,
);
}).toList(),
),
),
),
You can just Do this
decoration: const InputDecoration(
// enabledBorder: InputBorder.none,
// disabledBorder: InputBorder.none,
// focusedBorder: InputBorder.none,
// errorBorder: InputBorder.none,
border: InputBorder.none,
),
DropdownButtonFormField(
iconSize: 30,
decoration: InputDecoration(enabledBorder: InputBorder.none),
hint: Text(
"Select Duration",
style: TextStyle(fontSize: 20),
),
items: listDrop,
onChanged: (value) {
duration = value;
},
)
if you want just disable the border in all the case you can use :
DropdownButtonFormField(
validator: _validator,
decoration: InputDecoration(
border: InputBorder.none,
),
items: [],
onChanged: (value) {}),
),
if you want disable only when there is no error you can use this
decoration: InputDecoration(
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide: BorderSide(color: kLightBlackColor)),
),
This worked for me
DropdownButtonFormField<String>(decoration: InputDecoration(border: InputBorder.none),)
I want to make my TextField height the same as my container height. Please check my code below and let me know how can I make TextField match_parent of my container. I've checked this question The equivalent of wrap_content and match_parent in flutter? but I didn't find any solution. I need to make TextField to take full height and width of my container.
new Container(
height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new SizedBox.expand(
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
),
)
Please check the screenshot below. As said, I need my TextField to take full height of Container
Here is my solution:
Container(
height: 200,
color: Color(0xffeeeeee),
padding: EdgeInsets.all(10.0),
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 200.0,
),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: SizedBox(
height: 190.0,
child: new TextField(
maxLines: 100,
decoration: new InputDecoration(
border: InputBorder.none,
hintText: 'Add your text here',
),
),
),
),
),
),
),
It works pretty good for me. And here is a screen shot.
Answering this in 2021. There is an expands property available now. This code works:
Column(
children: [
Expanded(
child: TextField(
maxLines: null,
minLines: null,
expands: true,
),
flex: 1),
],
)
Let's remove a few lines in code and understand how flutter works.
Why we are giving height 200 to Container. Can't the Container adjust the height based on its child (in this case SizedBox.expand)
If we remove height 200, then Container occupied the entire screen because of SizedBox.expand
Do we really need the SizedBox for our use case. Let's remove that also see what happens.
Now our Container wraps the TextField. But there is some space above and below.
Who decided that space? TextField's decoration's contentPadding. Let's remove that also. It looks like below where textField wrapped by Container. Hope this is what you want. If not, please comment, we can tweak a bit and get what you want. Cheers
Final version of code which displays the above image
new Container(
// height: 200.0,
decoration: new BoxDecoration(
border: new Border.all(color: Colors.black)
),
child: new TextField(
maxLines: 2,
style: new TextStyle(
fontSize: 16.0,
// height: 2.0,
color: Colors.black
),
decoration: const InputDecoration(
hintText: "There is no data",
// contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
),
)
Currently the only way to achieve the TextField to fill the available vertical space is:
TextField(maxLines: 1000000) //maxlines: any large int
While it is tempting to use TextField(maxLines: null), it will just set the TextField to expand with its content, until it reaches its container limit.
I think there needs to be a bool stretchVertically parameter. TextField(stretchVertically: true) would mean that the TextField will try to fill as much vertical space as it can. stretchVertically and maxLines would have to be mutually exclusive.
i am trying to add alignment to the hint-text inside Text-field.but it is not working. How to bring it to centre??
How to write text in curved shape???
Container(
child: new TextFormField(
controller: _pass,
textAlign: TextAlign.center,
decoration: new InputDecoration.collapsed(
hintText: " PASSWORD", ), )),
use textAlign: TextAlign.center, inside TextFormField or textfield
here is the code
The Output Like This
My problem was the auto content padding:
TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0),
hintText: "hola mundo",
),
),
Happy coding.
The textHint will have the same Alignment as the input text. So you can try the code below to achieve what you're looking for:
TextFormField(
keyboardType: TextInputType.number,
maxLength: 5,
textAlign: TextAlign.center,
autofocus: true,
initialValue: '',
decoration: InputDecoration(
hintText: 'some hint',
counterText: "",
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
),
);
Note: specific case, but might help others who tried everything else from this thread.
I had a design from which I copied all the paddings and alignments, but I somehow couldn't center the hint text, it was always a few pixels closer to the top edge.
The only thing that worked was finding out that there was a specific text height set in the design. After I applied that, everything aligned perfectly.
InputDecoration(
hintStyle: TextStyle(
fontSize: _smallFontSize, // or whatever
height: 1.4, // <----- this was the key
),
// other properties...
);
you can add textAlign: TextAlign.center to your code
here is my code and its works:
new Padding(
padding: new EdgeInsets.all(30.0),
child:
new TextField(
textAlign: TextAlign.center,
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.teal)),
hintText: 'REF: 2',
),
),
),
all of the answers work for the fixed-sized text fields but in my case, I m using a dynamically sized container that parents my text field
AnimatedContainer(
width: (!widget.scrollController.hasClients ||
widget.scrollController.positions.length > 1)
? MediaQuery.of(context).size.width.toDouble()
: max(
MediaQuery.of(context).size.width -
widget.scrollController.offset.roundToDouble(),
(MediaQuery.of(context).size.width - 80.w).toDouble()),
duration: const Duration(milliseconds: 150),
constraints: BoxConstraints(maxHeight: 40.h),
margin: EdgeInsets.zero,
child: TextField(
controller: controller,
expands: true,
minLines: null,
maxLines: null,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
filled: true,
fillColor: MyAppColors.primaryColor1,
border: UnderlineInputBorder(
borderRadius:
BorderRadius.circular(15.w)),
prefixIcon: Icon(
Icons.search,
size: 20.w,
color: Theme.of(context).accentColor,
),
hintText: 'Songs, albums or artists',
contentPadding: EdgeInsets.zero,
hintStyle:
Theme.of(context).textTheme.subtitle2!.copyWith(
color: Colors.white.withOpacity(0.8),
fontSize: 18.sp,
)),
),
);
the solution that worked for me is that I set expand parameter to true and set these parameters:
minLines: null,
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.center
the min and max line must be set to null in order to expand.
that is the only solution I found cuz in another way my hint text gain extra padding even I set the content padding to zero my hint text is not centered in other screen sizes.
You can use following attribute of TextFormField:
textAlign: TextAlign.center
This used to work earlier but now it doesn't. There's a recently opened issue in flutter repo which you can follow
Edit
Now works as expected.
textAlign: TextAlign.center will move your focus too, i fix it with some empty spaces in hint text
hintText: ' this is centred text)',
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.
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.
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.
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,
)
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)),
),
),
),
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. Fixed height:
(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,
)
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 disable multi line property action in the keyboard ..
use this
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: //Number_of_lines(int),)
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,
),
),
),
)
]);
}
TextField has maxLines property.
Use Expanded widget for dynamic feels
Expanded(
child: TextField(
keyboardType: TextInputType.multiline,
minLines: 1,
maxLines: 3,
),
)
if above once not worked for you then try add minLines also
TextField(
keyboardType: TextInputType.multiline,
minLines: 3,
maxLines: null);
For autowrap just use null for maxLines
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
or
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
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.
Specify TextInputAction.newline to make a TextField respond to the enter key and accept multi-line input:
textInputAction: TextInputAction.newline,
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,
),
),
),
),
),