Is it possible to do inter widget communication via something like a notification/event bus?
I need to be able to tell one widget to react to something that happened in another and didn't want to create a hard link.
The notification listener will only fire is if it is higher in the widget tree than both of the widgets so that isn't probably a viable solution.
There are lots of ways to do this depending on your use case.
You could have them be AnimatedWidgets that are passed a ValueNotifier or ChangeNotifier as the listenable. You can see this pattern in the Gallery's animation example.
You could use StreamBuilder to have your widgets rebuild automatically when new events come in on a Stream. There aren't a lot of examples of this in the main Flutter repo, but it's something that you're likely to need once you start using plugins or doing network I/O.
You could use a GlobalKey to get currentState and have one State call methods on the other. This is how snackbars work (example).
You can also extend InheritedWidget to provide widgets with information that wasn't passed as a constructor argument, and they'll automatically be marked for rebuild when that information changes. This is how Themes work, for example.
If you can provide more details on what your widgets do / what their relationship is, or ideally a code snippet I can help you decide which approach would make the most sense for your situation.
Related
I am designing an application that uses setState to refresh a screen with all its widgets, however I would like to know if there is a way to exclude a particular widget (conainer) and all its children, as if I were treating it as a new page.
I tried to use Navigator.push (context, MaterialPageRoute), but it didn't work, I would like to treat the widget as a separate page. I appreciate any help
Short answer: You can't.
Long answer: You can change where the setState is called, create a separate StatefulWidget that contains only the ones that need to be rebuilded. However in most of the cases this is not possible because of the order you need to show your widgets or many other factors. That's when State Managements tools come in handy. You should try to learn how to use Provider, Riverpod or BLoC (which i personally recommend). If you want something a litte bit easier you can start learning how to use InheritedWidget starting in the documentation right here.
use const if possible. if not,
use StatefulBuilder , if you call setState inside this widget, the outside widget is not touched. Maybe it will suit what you need
Maybe I don't understand the purpose of BloC or Provider but I'm confused as to why we would ever want to use them instead of using Flutter's built-in state management using the Stateful widget. I've just finished an app and can't remember a point where I wished I needed something more than the defaults. Can anyone clear things up for me?
There are a few reasons to use a BloC or Provider rather than Flutter's built-in setState:
BloC and Provider offer a more robust way to manage state.
BloC and Provider make it easier to update state across multiple widgets.
BloC and Provider can be used to manage async data.
BloC and Provider offer a more modular way to structure your code.
There are some case that you need BLoC to make you easier to define each state or condition that happening inside the application.
We will start discussing creating app like https://www.tokopedia.com/ (inspect element and go with phone size preview). You will see that between widget section tokopedia_ss there are some loading animations, and when the data load complete the widget loading animation changed to viewable widget (as user).
in bloc, you will make stateLoading(), stateComplete(data), stateFailed(data). and in the controller or screen you can describe what will happen when bloc state is stateLoading etc...
Creating this case with setstate is more complicated and make your code messy, also setstate will make phone render all the Build() code. not like BloC builder, you can define each widget or section.
So, when there are 10 sections, using Bloc you able to make it render each state but when using standard setstate it will render all the 10 sections in one time every state changes.
More information about BloC: article_about_BloC
As the below diagram shows Stateful widget covers what Stateless widget do, When I can do the same thing with Stateful widget, why Flutter designers added another widget? For increasing performance?
Please do not post the difference just answer the Why?
Would you always use a sword to do a knife's job? Given that you always have both of them available with easy access. The knife can't do everything a sword can, but would that mean that a sword should be used by default for everything, since it's more robust?
You'll have many widgets where the state of the elements will not change, and others where you will not have to use setState to update your UI either(given that you would rather not use higher level state management solutions).
Using stateless widgets as long as they can do the job, means more performent widget trees.
Please do not post the difference just answer the Why?
Knowing the difference between them is key to understanding 'why', and the differences are not just in the name less vs full. But sensing that you aren't interested, that's why.
Good Flutter code seperates the code into many small Widgets. In addition to better performance creating a StatefulWidget means that you have to write more code and add unnecessary complexity to your code.
For better performance. Stateless widgets are usually only called in one of these three situations:
1- widget is inserted in the tree.
2- Widget's parent changes its configuration
3- Inherited Widget it depends on changes.
I've started to learning about Flutter's inherited widgets and i have a question.
Why do we need an InheritedWidget if we can get data from context.findAncestorOfExactType?
And that updateShouldNotify... Like, it notifies child widgets when some condition is true, and they are anyway running their build methods after InheritedWidget changed, because it's immutable and we can only chage it in some rebuild...
InheritedWidget is more useful for build method cases. When you want to get data from an ancestor inside your build method.
From the Flutter API: https://api.flutter.dev/flutter/widgets/BuildContext/findAncestorStateOfType.html
This should not be used from build methods, because the build context
will not be rebuilt if the value that would be returned by this method
changes. In general, dependOnInheritedWidgetOfExactType is more
appropriate for such cases. This method is useful for changing the
state of an ancestor widget in a one-off manner, for example, to cause
an ancestor scrolling list to scroll this build context's widget into
view, or to move the focus in response to user interaction.
Also by doing what you mention, you are coupling Widgets together which is not a good practice at all. Widgets are known to be able to moved from place to place without much modification.
There are many useful things that come from the Inherited Widget. Some of these things are very useful packages, I recommend that you take a look at them.
Provider package
InheritedWidget & InheritedModel
Redux
BLoC / Rx
GetIt
You can also take a look at the InheritedWidget documentation
I'm developing an app with lots of screens and pages. I've read somewhere that you should use Stateless Widgets whenever you can.
Why is that?
If I have a lot of screens, should those be stateless? And then the content inside be Stateful? Is it better to have both the screen and widgets inside being Stateful?
You should ask yourself some questions about the screen/page to decide if it will be Stateless or Stateful.
The most obvious, does it need to change state?
Do you need to call initState, didChangeDependencies or another lifecycle method?
Is a bad practice to make Stateful when not needed. A good idea might be to start always as Stateless widget and if needed you can change it to Stateful easily with Alt + Enter shortcut (Android Studio).
I always start by creating a Stateless Widget and work with it until I have to change something state. So I could quickly use `Alt-Enter/ Convert to a Statefull from Intellij/AS to change it to stateful. (doing the inverse is not so easy, so...).
Moreover, if you use Stateful widget with some async mechanism, like streams, you could build the widget once and use the streams to update the information you need, and it will not impact the performance of your app so much. But if you call setState many times, this can degrade your App, since for every setState the Widget tree will be rebuilt.
This article from the flutter docs shows interesting tips about handling state change in flutter apps: