I have a page with two main widgets: a futurebuilder that contains a list of elements taken from an api and an appbar.
The appbar content (a row of days) is grayed out depending on the result of the api (which returns a list of dates). When I interact with the appbar, that has a button to update the data from the api, it triggers a rebuild (with setstate I update the future with the api call). However, when FutureBuilder finishes and updates the state with the result, the appbar does not refresh. How can I force an update? I tried calling setstate from inside the futurebuilder but it doesn't work.
Thank you.
Related
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?
How can it update a list view elements without doing pull-to-refresh
If I'm adding an element in a dialog window or from an Api, how to add/update the list view elements automatically.
Should I use StreamBuilder?
Use state management pub like Getx, or something with adlistener.
Yes you can use stream builder and you can also use setstate
setState(() { });
StreamBuilder Widget builds itself based on the latest snapshot of interaction with a Stream. Thus the state of the app changes whenever new elements are added in the list as long as the connection status is active.
You can also use the combination of ListView Builder and setState method, though the state of the app needs to change whenever a new element is added. Earlier StreamBuilder widget was updating the state of the app. Various methods like adding a button to the screen, which can help the user manually change the state; can be used depending on the use case.
You can read more about it from the official docs: setState method
StreamBuilder
This answer is not exactly about updating listView, but updating a widget(PiChart). As listview is also a widget, the implementation will be the same to update without refreshing.
In this method, I am using streamBuilder to update the widget. so need not refresh the app to update the data.
https://stackoverflow.com/a/69800324/13577765
I have NestedScrollView(), one of the slivers is a progress bar widget. The problem is that I haven't pulled the data yet as it a firebase stream.
The body has a StreamBuilder() which gets the data and updates the progress variable which controls the progress bar.
The problem is that the progress is declared to be 0 and only when I get the data from my stream do I update it. But when it is updated I need to setState() to update the progress bar but I cannot call setState() during the widget build as that causes errors.
How can I rebuild a parent widget from a child or do something else to achieve what I want? In short, what I want is to rebuild the progress bar or the entire NestedScrollView() when the progress variable changes.
What I do is fetching items from Firebase then saving them in a list and then I display them in a ListView. The Problem that I have now is that I check if the list has Items and if so it displays my ListView with the Items and if there are no items it displays a Text but even but even if there are items the text gets displayed but after pressing hot reload the items get shown.
My guess was that there is a Problem with the State of the Widgets overall because stuff like SetState has no effect or a Refresh Indicator
Is there a reason why the StreamBuilder is following your masterListStart().asStream as opposed to the masterList stream? I'm not saying it's wrong, its just not immediately obvious.
Either way, it's not rebuilding automatically because the only part of your displayStory method that is reactive to the stream doesn't get built until after the non empty list condition is met. Without implementing a reactive state management solution there's nothing in your code that automatically notifies any listeners that the state of the storysList has changed, which means nothing is triggering a rebuild. Which is why you have to hot reload to see the changes.
Without me getting too deep into your code, try returning the StreamBuilder at the top level of the displayStory method and putting all the conditionals inside its its builder method.
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