setState blocks editing of TextEditingController - flutter

I am using a TextFormField as a widget and TextEditingController inside TextFormField for a phone number, and I am trying to validate a number while typing with the flutter_libphonenumber library, which provides an async function for validation.
I am trying to change the colour of the text depending upon validation status while entering it.
Current state:
Implemented TextFormField and providing it TextEditingController as a controller with valid initial text.
Implemented onFieldSubmitted and it works fine on tap of Done button of the keyboard.
Added listener to this controller for validation and set _isValid bool there.
I have used this bool to set colour of text inside the controller while building it.
So the current issue is, when I am entering text I get proper validated status inside the listener, but the colour of text is not changing accordingly.
I understand this is happening due to not calling setState after validation, so it will rebuild the widget and change the colour according to _isValid.
Error: When I try to setState inside the listener, it just doesn't allow editing.
Note: I have tried the same approach using onChanged method and it also does same, cannot enter or delete anything inside textField if there is pre-populated text (initialText).
Can anyone help me to solve this issue, or guide the correct path?
Thank you!

You can use the Form widget's autovalidate field by doing
Form(
autovalidate: true

Related

How can I code a editable textfield in a CustomPainter in Flutter

I have a CustomPainter extending class. Until now, I paint only rectangles with some static text in it. Now I want to improve this a little bit and want that the user of my Flutter-App can edit this text.
I added a TextEditingController to my Object-Class and tried this:
TextField textField = TextField(
controller: object.textController,
);
textField.createRenderObject(context).paint;
textFieldPainter.paint(canvas, Offset.zero);
}
Unfortunaly, there is nothing like a textField.createRenderObject-Function in Flutter. So I look for a idea how I can get my a "controlled Text" working.
I also played around with TextSpan(). But I can't set the Controller to this.
The following steps are not the best solution , but you can try this solution.
Steps:
create an OverlayEntry, put a (hidden) TextField into it with a FocusNode and TextEditController.
after added the overlay entry, request focus on the focusNode, so the keyboard will open.
Add an onChanged to the TextField, and notify the painter somehow (e.g. valueNotifier) on text change.
In the TextPainer use the TextEditController.text value
For me, the following solution fit:
I built a function that checks if a click was done within the dimensions of the rectangle. If yes, a "properties dialog" opens (currently only the text) and here the text can now also be changed.
I know, this is only a workaround and not a real solution to my question, but maybe the approach helps one or the other.

clearing text field when using flutter_bloc

I have a simple chat page with a ChatBloc and a ReplyBox widget, a message box with a send button.
The I would like the ReplyBox to be reusable, so not to have specific knowledge of the ChatBloc. However, I'd like to be able to control the text in the ReplyBox from the bloc. This is proving very difficult because the text field expects to use a TextEditingController.
What I've tried:
Using TextFormField initialValue to pass into the widget the text from the bloc. Doesn't rebuild when the value changes.
Forcing a rebuild using Key. Text is updated but focus is lost.
Making it a stateful widget with a TextEditingController, not taking the text value from the bloc, and just clearing when the button is pressed. This works ok, but it's not flexible. For example, the message would be cleared if there is a sending error, which it shouldn't.
I haven't tried managing the TextEditingController in the bloc. It seems like not the right thing to do.
I see the 3rd method is promising with StatefullWdiget and TextEditingController to solve your problem.
I would have another bloc for the ReplyBox with events like Reset, Update, etc.
In the widget I would connect the state of the ChatBloc to ReplyBloc.
In drawing may be something like this:
I have asked a similar question on the repository of BLoC library. Quoting the answer provided to me by Felix Angelov, the creator itself:
I don't recommend that. The proper way imo is to maintain a TextEditingController and call clear when you want to clear the input.
You can read the answer here plus you can also check the entire question.

Auto Scroll in an empty field during validation in flutter

I have created a form in flutter and during validation (when clicking on the button) I want it to scroll up to the empty field. I have tried many ways including FocusNode and because there are many textfields, its not working. I think I am doing it the wrong way. Can someone help?
create a diffrent focusNode for each TextFormField and then
call requestFocus() on the Node when the validation is false.
first some where
final FocusNode d = FocusNode();
then in the TextFormField Widegt
focusNode: d
then in your validat
d.requestFocus();
and redo that for every TextField and not forget to check for the currect Text Field in the validator

Change value of a Text widget (NOT TextField)

I am trying to set up a text widget in my flutter app, and have the value change based on other widgets.
I can only find tips on how to change a TextField, but I don't want this to be editable by the user, only by code.
I can't set the data value of the widget, because it's final.
Is there any way to make this work in Flutter?

Flutter TextFormField onChanged event

I want to build autocomplete using TextFormField, I don't know how to create OnChanged event for TextFormField
My requirement is there will be text field with some text, if user edits that text, textfield should behave like auto suggest.
Lucky for us the onChanged option in the TextFormField is already available. If you update flutter and doesn't work just go to the text_form_field.dart file by clicking on the Widget TextFormField + command/control and modify the text with code in the link:
text_form_field.dart
Are you wrapping TextFormField in a FormField widget? If not, I suggest to use just TextField which has an onChange property
Edit: To set an initial value you can add a TextEditingController and asign it to the TextFormField
TextEditingController _controller = TextEditingController();
then in initState() you can do
_controller.text = 'Initial Value'