Flutter TextField value always null on ios device? - flutter

I am currently testing my Flutter app on both my iPhone 8 and my Android moto G8.
However, the issue I am running into is that while everything works well on my Android moto G8, on my iPhone it seems that whenever I change a TextField the value in the previous TextField becomes null i.e.:
flutter: This is in error: 'package:firebase_auth/src/firebase_auth.dart': Failed assertion: line 174 pos 12: 'email != null': is not true.
But When I was typing on the device the printout is:
flutter: This is in email:test#gmail.com, value: test#gmail.com
Here is the code for my custom textfield:
class InputTextFields extends StatefulWidget {
InputTextFields({this.title, this.obscureText, this.setValue});
final String title;
final bool obscureText;
Function setValue;
final TextEditingController _controller = TextEditingController();
#override
_InputTextFieldsState createState() => _InputTextFieldsState();
}
class _InputTextFieldsState extends State<InputTextFields> {
#override
Widget build(BuildContext context) {
String hintText;
return Container(
padding: EdgeInsets.only(bottom: 10, left: 35, right: 35),
child: TextField(
obscureText: widget.obscureText,
decoration: InputDecoration(
labelText: widget.title,
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.grey,
),
),
hintText: hintText,
),
onChanged: widget.setValue,
),
);
}
}
So I am sure the TextField is working as intended but the error still persists. Any ideas how I can solve this?

The problem seems to be from your onChanged: widget.setValue in your TextField. Your function is making the previous TextField null. The best way to retrieve the value of a TextField is to use a TextEditingController. In order to use a TextEditingController in your custom TextField, you would have to pass it as a parameter.
class InputTextFields extends StatefulWidget {
InputTextFields({this.title, this.obscureText, this.controller});
final String title;
final bool obscureText;
final TextEditingController controller;
}
In your TextField:
controller:widget.controller
This is how you use that new custom TextField:
final TextEditingController myController=TextEditingController();
InputTextFields(title:"Test",obscureText:false,controller:myController),
I think you are trying to validate if the TextField's value is an email or not. You could easily check it by using RegExp or by using https://pub.dev/packages/email_validator package. You could also use TextFormField instead of TextField to check if the TextField's value is null. Have a look at this: https://flutter.dev/docs/cookbook/forms/validation. Good Luck!

Related

Optional IconData on constructor

I'm studying Flutter, so I'm just a newbie.
I tried to create a widget with an optional IconData type parameter in the constructor, but I was getting an error.
I got added "?" in front of the local variable. From then on, I just had to enclose the constructor parameters in "{ }". I've found a way to make it work, but I'm not sure it is the best/correct way to do so.
If you have any tip, I'll be happy to hear it!
That's my code:
class Editor extends StatelessWidget {
final TextEditingController controlador;
final String label;
final String hint;
final IconData? fieldIcon;
Editor(
{required this.controlador,
required this.label,
required this.hint,
this.fieldIcon});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: TextField(
controller: controlador,
style: const TextStyle(
fontSize: 24.0,
),
decoration: InputDecoration(
labelText: label,
hintText: hint,
icon: fieldIcon != null ? Icon(fieldIcon) : null,
),
),
);
}
}
Your code is correct. Nothing inappropriate in my opinion.
However, I feel the following checking for is redundant:
icon: fieldIcon != null ? Icon(fieldIcon) : null,
Given that the icon property of InputDecoration already takes a nullable icon, why not give it just that?
Maybe change the type of fieldIcon from IconData? to Icon? itself. Then, where you consume the icon in the InputDecoration, simply give it the nullable fieldIcon:
icon: fieldIcon,
But wherever you use this Editor widget, remember to give it an Icon for fieldIcon and not an IconData.

Flutter - different colors for initial value and user input in textfield

Basically what I'm trying to do is to supply an initial value (grey) to a text field and once the user clicks the text field, the initial value is automatically cleared and the user input should be black. Currently my code is like this.
TextEditingController _controller;
FocusNode _focusNode;
#override
void initState() {
super.initState();
_controller = TextEditingController(text: 'Search');
_focusNode = FocusNode()..addListener(_onFocus);
}
#override
void dispose() {
_focusNode.dispose();
_controller.dispose();
super.dispose();
}
void _onFocus() {
if (_focusNode.hasFocus) _controller.clear();
}
Widget _buildSearchBox() {
return CupertinoTextField(
controller: _controller,
focusNode: _focusNode,
style: TextStyle(
fontSize: 17,
color: _focusNode.hasFocus
? CupertinoColors.black
: CupertinoColors.systemGrey,
),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
),
);
}
I know it doesn't work because: (a) everytime the user types something, does something else and clicks the text field again, his input is cleared (b) I hope only the initial value is grey, but once the user does something else, his input also becomes grey.
Can anyone help me with it? Thanks.
From what I understood from the question, one way you can do this is something like this
FocusNode _focusNode;
#override
void initState() {
super.initState();
_focusNode = FocusNode()..addListener(_onFocus);
}
void _onFocus() {
setState((){});
}
Widget _buildSearchBox() {
return CupertinoTextField(
placeholder: "Search",
focusNode: _focusNode,
style: TextStyle(
fontSize: 17,
color: _focusNode.hasFocus
? CupertinoColors.black
: CupertinoColors.systemGrey,
),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
),
);
}
#override
void dispose() {
_focusNode.dispose();
super.dispose();
}
Add a placeholder field see you cannot style it, individually as
It is a lighter colored placeholder hint that appears on the first line of the text field when the text entry is empty.
Defaults to having no placeholder text.The text style of the placeholder text matches that of the text field's main text entry except a lighter font weight and a grey font color.
CupertinoTextField(
placeholder: "Enter Email", //Add this and your work is done
controller: _controller,
focusNode: _focusNode,
style: TextStyle(
fontSize: 17,
color: _focusNode.hasFocus
? CupertinoColors.black
: CupertinoColors.systemGrey,
),
decoration: BoxDecoration(
color: CupertinoColors.systemGrey6,
),
);

Flutter: Set default TextField property across the whole app

Is there a way I can set the default TextField textCapitilisation to TextCapitilisation.sentences so that I do not have to add to it every TextField?
Ideally in ThemeData?
Like # F Perroch said, I don't think that is possible too but you can create a Custom TextField for all of your TextField Widgets and use them where appropriate like the exmaple below:
Create a CustomTextField widget like below
class CustomTextField extends StatelessWidget {
/// define property of text fields you want here
final String hinText;
final String labelText;
final Widget icon;
final TextStyle labelStyle;
CustomTextField({this.hinText, this.labelText, this.icon, this.labelStyle});
#override
Widget build(BuildContext context) {
return TextField(
// set your text capitalization here
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
/// set other properties here
hintText: hinText,
labelText: labelText,
labelStyle: labelStyle,
prefixIcon: icon,
),
);
}
}
Call the CustomTextField widget anywhere like below
CustomTextField(
hintText: 'Hello',
labelText: 'Hi there',
labelStyle: TextStyle(....),
icon: Icon(Icons.person)
),
I hope this answers your question.

Flutter Why my textfield lose the value when I dont focus on it?

I made a class and it has a controller and a widget that includes a padding within a textfield.
Now when I change the focus from the textfield to something else it lose the value.
this is my code.
`
class RxInput {
final String hindText;
final bool obscureText;
Widget widget;
final TextEditingController controller = new TextEditingController ();
String get value => controller.text;
RxInput (this.hindText,context,{this.obscureText = false}) {
widget = Padding (
padding: const EdgeInsets.all(20.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.blue.shade200,
elevation: 5.0,
child:TextField(
controller: controller,
decoration: InputDecoration(
hintText: hindText,
border: InputBorder.none,
alignLabelWithHint: true,
),
obscureText: obscureText,
)
),
);
}
}
`
I solved this question. You should initialize your variable in the initState instead of build.

Flutter: How to change TextFormField prefixIcon not focus color by ThemeData?

Flutter: I could change the TextFormField prefixIcon focus color by setting Theme.accentColor, but can't find any way to change the prefixIcon color when not focus.
Use FocusNode Class, this will keep a track of when you have the focus on that particular TextFormField.
Note: Make sure you assign different FocusNode object to different TextFormField() if you have multiple class.
Here is your solution:
FocusNode _focusNode;
#override
void dispose() {
super.dispose();
_focusNode.dispose();
}
#override
void initState() {
super.initState();
_focusNode = new FocusNode();
_focusNode.addListener(_onOnFocusNodeEvent);
}
_onOnFocusNodeEvent() {
setState(() {
// Re-renders
});
}
TextFormField(
focusNode: _focusNode
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: Padding(
padding: EdgeInsets.all(0.0),
child: Icon(
Icons.search,
color: this.getPrefixIconColor(),
) // icon is 48px widget.
)
)
)
//This will change the color of the icon based upon the focus on the field
Color getPrefixIconColor(){
return _focusNode.hasFocus ? Colors.black : Colors.grey
}
Let me know if that helps. Thanks