Updating widget value on render? - flutter

I have a Flutter app, and I want to display a color depending on the current system time in milliseconds since epoch. Of course, I cant refresh the state of the widget several times a second to change the color. But how can I achieve this effect? Is there some kind of render-method I can override?
P.S.: I am using a Material widget to display the color.

Flutter updates the view only when a new frame is due, no matter how often you called setState() since the last frame.

Related

Manage Device Sizes MediaQuery Globally

What is the proper way to handle device size globally. The idea is not to have a [MediaQuery.of(context).size.width] on each screen of the app. There is already a question and answer about it, but the only answer is out of date because there was no null safety yet.
The answer suggests creating a constants.dart file, like in the image below:
1
And initialize in the build of the first widget of the application:
2
The problem is that for it to be constant it must have a value, and not wait for the first build. It is also true that the value canchange based on device orientation and I would like to handle this as well.
I have doubts about it. if someone can help me
You cannot save the screen dimensions as a constant, because they will change if the device is rotated, or when the screen is resized, such as for desktop and web apps.
Instead you should be pushing your cutpoint decisions as low as possible, using LayoutBuilder.
LayoutBuilder seems preferable over every use of MediaQuery for sizing a viewport (either the whole screen, or the space left in a column or other layout).
LayoutBuilder also works hard to avoid rebuilding its child if the size doesn't change and the parents haven't had to re-layout.
The builder function is called in the following situations:
The first time the widget is laid out.
When the parent widget passes different layout constraints.
When the parent widget updates this widget.
When the dependencies that the builder function subscribes to change.
The builder function is not called during layout if the parent passes the same constraints repeatedly.
And you don't have to think about "the height of the appbar" ever again, because you're getting the space left, not the total space on the screen.
Check it out: https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html

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 to preserve the selected tab in Flutter upon orientation change?

I have an app with Tabs in Flutter and when I change orientation by rotating the device from portrait to landscape, the widget tree gets rebuilt and the state of the widgets gets reset. The effect is that the selected tab is reset back to the first tab. I would like to prevent the state from being reset during orientation changes so that the selected tab does not also change.
In my State class I'm using the AutomaticKeepAliveClientMixin and have set:
#override
bool get wantKeepAlive => true;
but that does not seem to have any effect.
Is there a way to ensure that all of my application and widget states are preserved when the device is rotated?
I can post code if that would be helpful, although I expect that this is a fairly generic question with a simple answer that I have not thought of yet.
Thanks!
As it turns out, after tracing all the way back through my Widget tree, I discovered that my topmost widget was declared as Stateless and I had placed a line of code in the .build method that resulted in the state of the entire app getting reset each time the widget was rebuilt - particularly on orientation changes.
To fix, I changed the widget to Stateful and moved this code into the state class into the initState method. Once I did this, my problem was resolved because the state of this class is not affected on an orientation change.
Remi was right on the money with his comment.
A full day of coding lost, but a lot learned. :-)
To anyone who might come across a similar problem, take a very close look at any code you place into a .build method and realize that it will get called any time the widget is rebuilt.
Still learning Flutter, but overall impressed.

Skip re-building a heavy loading widget when it is not currently viewed

I have a flutter screen widget A containing 10000 elements. It takes time to load this widget every time when flutter build it.
At the same time, I do Navigator.push in this widget to open a new screen B.
Every time when I push a new screen C in screen B, or pop the screen C, flutter re-build the widget A. It takes time to build the screen widget A while that screen is currently not being viewed. It is just in the background.
I would like to skip building the screen widget A if it is not veiwed.
May I know is it possible to do so?
Many thanks!
You could try setting https://docs.flutter.io/flutter/material/MaterialPageRoute/maintainState.html false,
or just store the widget in a variable and return the same instance every time build() is called..

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