Text getting cleared when using TextEditingController and StreamBuilder - flutter

I have observed some strange behaviour when using TextEditingController and FocusNode in combination with StreamBuilder, namely:
Text inside a TextField getting cleared when unselecting the text field
Two input carets being active at the same time on two separate text fields
This happens when all the following conditions are met:
A stateless widget creates its own TextEditingControllers and FocusNodes.
These are used within some TextField widgets.
The stateless widget's build method returns a StreamBuilder, which rebuilds the widget contents (including the TextFields) when new values are pushed to the stream.
The stateless widget is presented as a MaterialPageRoute.
NOTE: if the stateless widget is not presented, but is presented directly when the app starts, the issue does not appear.

The problem was on my end. The issue was that I was persisting objects inside a StatelessWidget.
You shouldn't.
Opening the keyboard tends to rebuild the whole screen (which is fine). But in my case rebuilding cause your TextEditingController to be GCed because you stored them inside a StatelessWidget
So the reason that this works with StatefulWidget is that the state is retained even across rebuilds, so I can use it to hold my TextEditingControllers.

Related

HookConsumerWidget in flutter causing dispose errors

In my flutter app, i use a list view inside a HookConsumerWidget, this list has a filter and once it filters the list tiles have big gaps, and i see this error:
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
i couldn't solve it because its a HookConsumerWidget and its not flexible
try to show some code snippets of the problem or the log messages,
my concern is when you're using HookConsumerWidget you don't need to use setState as you could manage the UI changes directly with listeners or watcher with 'StateProvider' for example.

Using Riverpod for Flutter state, what's better: ConsumerWidget or just a Consumer where needed?

I'm fairly new to Riverpod but it seems that using a ConsumerWidget as the body of a screen is a bad practice because the screen is rebuilt when not needed.
For example:
the main widget (the screen itself) is a ConsumerWidget
somewhere in the hierarchy I have a list of clickable buttons, for which I'm watching a ChangeNotifierProvider to update a selected index (only one button can be clicked at a time).
It seems that whenever I click one button to update the index (and change the color of the button), the main widget's Build method is called, along with the items in my list.
However, when using just a Consumer widget inside the itemBuilder method of my ListView, clicking one button no longer triggers the build method of the main widget.
So, is it considered a good practice to just use Consumer widgets where needed?

Choosing StatelessWidget or StatefulWidget for sub-widget which has TextEditingController as a child

I'm working on a refactored code to separated small piece of widgets.
There's several columns with TextFields in each one of them.I have two options to complete the task :
Choosing StatelessWidget since it have more performance, may put TextEditingController related code outside of sub widgets. Or include some logic in onChanged event. but still there's some events like clear text can't put in onChanged event
Choosing StatefulWidget if I use TextEditingController include inside each sub widget.
How to choose between StatelessWidget and StatefulWidget when refactoring code into small widgets like this ?
Update
Here's my current conclusion which can be updated if it's not correct.
Prefer to put FocusNode of TextEditin parent since it's related to brother focusNode & parentNode;
Prefer to put TextEdtingController in parent, which will be useful in cases like when TextField is out of screen like a ListItem scrolled out of the screen, which will make the whole widget unmounted. The state will be preserved.
Preferring to put animation self like shaking TextField when inputting something wrong in self. Since it's a feature of the TextField not related to the parent.
Edit in response to the discussion in the comments section:
You should go with the second approach when refactoring your code into smaller StatefulWidgets. And the parent should have a function to alter the nested TextFields' content and its animation behavior by calling functions inside it, as you earlier indicated you need to manage this behavior.

Flutter TextField focus rebuilds widget if keyboardType changes

Trying to build my first app on Flutter, but ran into a problem. Searched a lot, but everyone is having a bit different problems (keyboard closes, stream calls, etc.)
I try to use BLoC pattern and rxDart to listen and validate fields. Everything works well if all TextFields have same keyboardType, but I have different inputs (number, link, ...) and every time I tap on an input, keyboard is changed and that triggers Widget to rebuild.
Any way to keep my Streams intact of rebuilding a widget on keyboard change?
Edit: Actually the same happens if I use ShowDialog() on that page and close it with Navigator.of(context).pop();. I understand it's a page change and widget gets rebuilt, but how can I keep data in BLoC's streams of that widget?
Or how do I add to sinks my inputs' values after widget is rebuilt?

How many setState() calls is overkill for Flutter?

I am new to Flutter and reactive programming is also new thing for me.
Let's say I want to build a timer with Flutter.
I add a Scaffold with all the necessary stuff in it and I add a IconButton which starts the Stopwatch and Text which displays elapsed time. I also add Timer.periodic to periodically (every 0.5 second) update the text.
Text Widget controls it's own state by checking if Stopwatch is running and updating it's values.
So now let's say I want to have more complicated logic that changes the text based on some actions with other buttons which are the siblings of Text. However it is not possible to call setState of Text widget directly from sibling widgets. As I understand the point of reactive paradigm is that the state can be passed down the Tree. However if I make my Scaffold as StatefulWidget and update the state of the parent every 0.5 second it will redraw my entire Scaffold with all it's children. So eventually when the Scaffold gets big enough it will have to update everything instead of single Text widget.
Am I correct? And is there any solution to this. I read something about Streams and Sinks however it looks very complicated and I think that there should be another solution.
You don't need to rebuild the whole tree, if the state only changed in a sub widget, ideally you want to call set state in that widget so only that part of the tree (the one whose state changed) is rebuilt.
Streams aren't really that complicated, it's a good way for you to send messages between different components in your app, which is what you're trying to do here.
In your case you can also use a ValueNotifier to store state in the parent widget, or maybe an AnimationController, and send its listener down to the sub widget that needs be updated on change.
In any case, the state is lifted to a parent widget, which then becomes accessible to the sub widget through a listener, or a stream. When the listener triggers a signal, you rebuild the sub widget only.
Extract out widget and call setState() form that widget and it's don't render all the widget again