Show the suffixIcon after the suffixText in a textField - flutter

I just wanted to show the suffixIcon after the suffixText.
Now I know that in the InputDecoration documentation says explicitly that it will show the suffixText before the suffixIcon.
What would I like to do is:
the '*' represents that it's a mandatory field.
And I'm getting this :
is there a way for me to change the order of the suffixes in my TextField?
I tried using SizedBox, or Container widgets but never got the result I wanted.

You can use suffix (edit: suffixIcon) property and pass in a Row widget instead. Put both elements in the Row, and you can decide exactly how you want them to appear. For example:
Soure code:
TextField(
decoration: InputDecoration(
suffixIcon: Row(
mainAxisSize: MainAxisSize.min, // <-- important
children: const [
Icon(Icons.visibility, color: Colors.grey),
SizedBox(width: 4), // add a small gap
Text('*'), // second element
],
),
),
)

Try below code, use Row() widget for suffixIcon
TextField(
decoration: InputDecoration(
suffix: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Icon(
Icons.visibility,
color: Colors.green,
),
SizedBox(width: 5),
Text(
'*',
style: TextStyle(
color: Colors.red,
),
),
],
),
),
),
Your result screen->

You can modify your suffixIcon property to:
suffixIcon: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(Icons.remove_red_eye),
Text(
"*",
style: TextStyle(color: Colors.red),
)
],
),
),
The alignments here are important to maintain.

Related

Flutter widgets so confusing [duplicate]

I’m getting a rendering exception that I don’t understand how to fix. I’m attempting to create a column that has 3 rows.
Row [Image]
Row [TextField ]
Row [Buttons]
Here is my code to build the container:
Container buildEnterAppContainer(BuildContext context) {
var container = new Container(
padding: const EdgeInsets.all(8.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
buildImageRow(context),
buildAppEntryRow(context),
buildButtonRow(context)
],
),
);
return container;
}
and my buildAppEntryRow code for the text container
Widget buildAppEntryRow(BuildContext context) {
return new Row(
children: <Widget>[
new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
)
],
);
}
When I run I get the following exception:
I/flutter ( 7674): BoxConstraints forces an infinite width.
I/flutter ( 7674): These invalid constraints were provided to RenderStack's layout() function by the following
I/flutter ( 7674): function, which probably computed the invalid constraints in question:
I/flutter ( 7674): RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:256:13)
I/flutter ( 7674): The offending constraints were:
I/flutter ( 7674): BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
If i change buildAppEntryRow to just a TextField instead like this
Widget buildAppEntryRow2(BuildContext context) {
return new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
);
}
I no longer get the exception. What am I missing with the Row implementation that is causing it to not be able to calculate the size of that row?
(I assume you're using a Row because you want to put other widgets beside the TextField in the future.)
The Row widget wants to determine the intrinsic size of its non-flexible children so it knows how much space that it has left for the flexible ones. However, TextField doesn't have an intrinsic width; it only knows how to size itself to the full width of its parent container. Try wrapping it in a Flexible or Expanded to tell the Row that you're expecting the TextField to take up the remaining space:
new Row(
children: <Widget>[
new Flexible(
child: new TextField(
decoration: const InputDecoration(helperText: "Enter App ID"),
style: Theme.of(context).textTheme.body1,
),
),
],
),
You get this error because TextField expands in horizontal direction and so does the Row, so we need to constrain the width of the TextField, there are many ways of doing it.
Use Expanded
Row(
children: <Widget>[
Expanded(child: TextField()),
OtherWidget(),
],
)
Use Flexible
Row(
children: <Widget>[
Flexible(child: TextField()),
OtherWidget(),
],
)
Wrap it in Container or SizedBox and provide width
Row(
children: <Widget>[
SizedBox(width: 100, child: TextField()),
OtherWidget(),
],
)
you should use Flexible to use a Textfield inside a row.
new Row(
children: <Widget>[
new Text("hi there"),
new Container(
child:new Flexible(
child: new TextField( ),
),//flexible
),//container
],//widget
),//row
The solution is to wrap your Text() inside one of the following widgets:
Either Expanded or Flexible. So, your code using Expanded will be like:
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Demo Text",
hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
),
),
),
As #Asif Shiraz mentioned I had same issue and solved this by Wrapping Column in a Flexible, here like this,,
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
body: Row(
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Container(
child: TextField(),
)
//container
],
))
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
));
}
}
The InputDecoration of a TextField can cause an infinite width problem when placed inside a Row. Flutter explains this in the InputDecoration constraints property documentation:
Typically the decorator will fill the horizontal space it is given. ... If null, then the ambient ThemeData.inputDecorationTheme's InputDecorationTheme.constraints will be used. If that is null then the decorator will fill the available width with a default height based on text size.
So, the good news is that the width of a TextField can be constrained without the use of surrounding widgets like Expanded. Simply provide an instance of BoxConstraints to the constraints parameter of the InputDecoration that the TextField widget uses:
const TextField(
decoration: InputDecoration(
constraints: BoxConstraints.tightFor(
width: 200,
),
),
)
As mentioned in the Flutter documentation above, a set of constraints can be applied to several widgets at once by using a Theme with a ThemeData that specifies an InputDecorationTheme with the desired constraints for descendent widgets of the Theme to inherit from and use.
Row(
children: [
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 5.0,right: 5.0),
child: TextFormField(
controller: commentController,
validator: (String value){
if(value.isEmpty){
// ignore: missing_return
return 'Comment cannot be blank.';
}
},
decoration: InputDecoration(
labelText: "Comment",
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.green))),
),
),
),
],
),
I had the same problem.
If you want, you can use Table widget to avoid this kind of issue with TextField
A simple solution is to wrap your Text() inside a Container().
So, your code will be like:
Container(
child: TextField()
)
Here you also get the width and height attribute of a container to adjust the look and feel of your text field. No need to use Flexible if you are wrapping your text field inside of a Container.
If you want your TextField to size itself horizontally based on its content then you can wrap it with IntrinsicWidth widget.
Row(
children: [
Text("From"),
SizedBox(width: 10,),
IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "Start Date Start Date Start Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),),
SizedBox(width: 10,),
Text("To"),
SizedBox(width: 10,),
IntrinsicWidth(child: IntrinsicWidth(child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: "End Date",
hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
border: InputBorder.none,
),
),)),
],
)
But before using it in your code make sure to know what Flutter says about this widget.
Creates a widget that sizes its child to the child's intrinsic width.
This class is relatively expensive. Avoid using it where possible.
the best solution is with absouluts space values
Row(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: _telephonePrefixInput()
),
SizedBox(width: MediaQuery.of(context).size.width * 0.02),
Expanded(child: _telephoneInput()),
],
),

Flutter: Why is there so much space between the children of the Column widget?

My app needs to have 2 Texts that are to be placed one after another in the vertical direction. So I decided to use a Column widget. I didn't place a SizedBox between the 2 children of the Column, but they have already got quite a large amount of space in between them.
What can I do to get rid of the space? I set the mainAxisAlignment property of the Column to center, but that doesn't appear to be working.
body: Stack(
children: <Widget> [
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/img1.jpg'),
fit: BoxFit.cover
),
),
),
Padding(
padding: const EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
Expanded(
child: Text(
quotationToDisplay,
style: const TextStyle(
fontFamily: "Bangers",
fontSize: 26.0,
backgroundColor: Colors.red
),
),
),
Expanded(
child: Text(
authorToDisplay,
style: const TextStyle(
fontSize: 23.0,
backgroundColor: Colors.yellow
),
),
)
],
),
),
],
)
You have Expanded as parent of two texts inside of Column, that force to set all space posible to the widget. Remove Expanded.
Because you are using Expanded, they are expanded equally on the main access, try not to use Expanded or add flex: 2 to the second Expanded.

Flutter widget Alignment

I want to align the (+,-) icons and TextField on same Vertical Position. But i'm not getting this.
Here is My Code.
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
child: Icon(Icons.remove ,color: Colors.white),
onTap: (){},
),
Container(
width: 35,
height: 40,
child: TextField(
inputFormatters:[WhitelistingTextInputFormatter(RegExp(digit_Reg_Expression))],
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
cursorColor: Colors.green,
controller: Controler_size[index],
),
),
InkWell(
child: Icon(Icons.add,color: Colors.white),
onTap: (){},
)
],
)
Please Help me to position these Widgets Vertically so that they align in the same vertical position.enter image description here
If you want to place elements vertically, use the Column widget.
If you want to place elements horizontally use the Row widget.
Check the code below: It works perfectly:
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
InkWell(
child: Icon(Icons.remove ,color: Colors.white),
onTap: (){},
),
Container(
width: 35,
height: 40,
child: TextField(
inputFormatters:[WhitelistingTextInputFormatter(RegExp(digit_Reg_Expression))],
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
cursorColor: Colors.green,
controller: Controler_size[index],
),
),
InkWell(
child: Icon(Icons.add,color: Colors.white),
onTap: (){},
)
],
)
I hope this helps.
I followed the link you attach in the question, I think the problem is at your Container which wraps the TextField:
Container(...
width: 35,
---> remove this: (height: 40) ...
)
set mainAxisAlignment to MainAxisAlignment.center

How to set up a numerical input and not have body disappear in flutter?

So, I'm trying to get a numerical input for a price range set up. And yet no matter what I do from looking elsewhere, when I run it, the body is blank. Here's what I'm trying to get it to look like: price input range
And here's my code for it:
Align(
alignment: Alignment.centerLeft,
child: Container(
color: Color(0xFFffffff),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(
'\$',
),
TextField(
controller: _textFieldController,
keyboardType: TextInputType.number,
),
new Text(
'To',
),
new Text(
'\$',
),
TextField(
controller: _textFieldController,
keyboardType: TextInputType.number,
),
],
),
),
),
You have to wrap your Textfield with Expanded widget in following way.
Expanded(
child: TextField(
controller: _textFieldController,
keyboardType: TextInputType.number,
),
),
But if you want to limit your TextField widget's width then wrap TextField in following way.
Container(
width: 50,
child: Row(
children: [
Expanded(
child: TextField(
controller: _textFieldController,
keyboardType: TextInputType.number,
),
),
],
),
),
Note: Here you are using same controller for two TextField, which will not give you correct value of textfield, so have to provide different controllers.

How to align DropdownButton next to a TextField in Flutter?

I would like to vertically align a DropdownButton right next to a TextField.
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DropdownButton<String>(
...
),
Flexible(
child: TextField(
...
),
),
],
)
The current behavior is:
As you can see, the bottom lines aren't aligned. I guess that's happening due to a differences in height. What would be a good practice to fix that? (I'm guessing not using a fixed height)
My final goal is something like this:
Where both lines and the text of DropdownButton and TextField are vertically aligned.
Hope this helps but I got it working! Key prop that did it for me was setting contentPadding for widgets in row to 0.0
Row(
children: <Widget>[
Flexible(
flex: 2,
child: TextFormField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
labelText: 'Width',
contentPadding: EdgeInsets.all(0.0),
),
onChanged: (String newValue) {
_stashItem.width = "$newValue $_widthUnit";
},
)),
Flexible(
flex: 1,
child: DropdownButtonFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0.0)
),
value: _widthUnit,
items: ['cm', 'm', 'in', 'ft', 'yd']
.map((String unit) =>
DropdownMenuItem<String>(
value: unit, child: Text(unit)))
.toList(),
onChanged: (value) => setState(() {
_widthUnit = value;
})),
)
],
),
A bit late, but I had the same issue albeit with a slightly different layout:
I used TextFormField rather than TextField.
I used DropdownButtonFormField rather than DropDownButton.
Both fields were wrapped in Flexible widgets within the Row, with mainAxisSize set to MainAxisSize.min.
My text field was laid out to the left of the dropdown.
That being said, setting crossAxisAlignment to CrossAxisAlignment.end worked for me.
Try this:
Row(
mainAxisSize: MainAxisSize.min, // see 3
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible( // see 3
child: DropdownButtonFormField<String>( // see 2
...
),
),
Flexible(
child: TextFormField( // see 1
...
),
),
],
)
I am not sure whether this solution helps you or not, but I think its better than using row.
TextField(
decoration: InputDecoration(
prefix: DropdownButton(underline: Container(), ...)
),
)
Try this:
Row(
Row(mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end
children: <Widget>[
Expanded(
flex: 1
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<String>(
...
))),
Expanded(
flex: 6
child: TextField(
...
),
),
],
)
Try this:
Container(
decoration: BoxDecoration(
border: Border(
//TODO: Customize the underline here
bottom: BorderSide(
color: Colors.white70,
width: 0.5,
),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
DropdownButton<String>(
onChanged: (c) {},
underline: Container(),
items: [
DropdownMenuItem<String>(
child: Text('Email'),
)
],
),
Flexible(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
],
),
),
I ended up editing the padding of the TextField's content, and used CrossAxisAlignment.center instead of CrossAxisAlignment.start:
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
DropdownButton<String>(
...
),
Flexible(
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(6.0),
),
),
),
],
)
Result:
(You see space between them due to a SizedBox added)
You can simply decrease contentPadding in InputDecoration of DropdownButtonFormField