When does my class need a build() method? - flutter

I understand the general approach to building UI layouts using Flutter. However, I'm still unclear which classes or UI widgets require a .build() method when I'm creating my own vs. using the defaults generated by the project.
I haven't found a clear explanation yet - even in the Flutter tutorials. They all seem to just gloss over how "the build method takes a BuildContext" and then go on to the next subject without explaining further.
Does anyone have a succinct explanation of the build method and when it is or isn't needed? And more specifically: what does it actually do?

build() method describes the part of the user interface represented by this widget.
The framework calls this method in a number of different situations:
After calling initState.
After calling didUpdateWidget.
After receiving a call to setState.
After a dependency of this State object changes (e.g., an InheritedWidget referenced by the previous build changes).
After calling deactivate and then reinserting the State object into the tree at another location.
You can find more Here
TLDR: The build methode is used to create a new widget tree by placing the Widget reurned in the page tree. This method is essentially called when you create or update the widget (by calling setState((){})

Related

Where is Flutter's Navigator declared?

When creating a Flutter application,
we use a Navigator to move back and forth between screens.
In my application, I have some class instances that
I want to share with all child widgets in the hierarchy.
An example is a Data Base driver class (stateful)
which holds all functionality of reading/writing to the actual database.
Currently - the 'main' function is initializing it,
then the resulting object is passed through all
constructors of the participating widgets.
How do I make it behave like the Navigator
so it would be available in the global scope
without importing it or passing it through a chain of constructors?
I would gladly accept any other approaches,
and still, if you can also address the exact question - I would be grateful :)
I opened the code of Navigator, Stateless and Stateful widgets,
I tried to google for the source of that Navigator instance
but came up with nothing helpful.
Have you tried using InheritedWidget?
From the docs:
Base class for widgets that efficiently propagate information down the tree.
Create DataBaseDriver class as inherited Widget class, access it in its child class using context as DataBaseDriver.of(context)

where to write logic for every widget in flutter?

I know this is a basic question but I wanna know how you guy's implement logic for your widgets. I normally write logic in build() function just above the return type.
What do you mean by logic..?? If you are talking about like adding some values.. then we use a different method for that outside the build Method because build method will rebuild when the set state method called so some times logic can be used inside the build but some time we need to write the logic in different method and called them..
Build method will rebuild every time the app state got change or refresh
if you talking about widget state
You can write it in separate file using state management approaches like (Getx,Provider)
You can write it in separate function if you need to perform setState that method will update the state
...Try to use separate functions and controllers for logic it will help you in scalability for your code
If you write your logic in build method means it will rebuild every time when the page is refreshed.
I will suggest you to follow MVVM(Model View ViewModel) architecture, so that all the business logics can be written in controllers (ex: cart_controller.dart) .So that your files are separated from actual widgets.
UI goes into - cart_page.dart,
Logic goes into - cart_controller.dart

Add AppBar actions from Scaffold children such as from Fragment.onCreateOptionsMenu in Android (using InheritedWidget)

In Android, every Fragment can partecipate in populating the options menu (aka "appBar actions", in flutter terms) of the activity, using the Fragment.onCreateOptionsMenu callback.
I would like a similar mechanism also in flutter, i.e. that some widgets are able to add buttons ("actions") to the AppBar.
Threads had already been opened on this topic, but none reports a fully functional example and contains solutions to the precise technical problem I encountered.
To do this, I had thought of using the following 'typical' structure:
a StatefulWidget -to which I have given name ScaffoldHandler (ScaffoldHandlerWidget/ScaffoldHandlerState)- which wraps the entire Scaffold, and which uses InheritedWidget so that widgets further down the widgets tree can get a reference to it in an optimal way (using the classic of() method which executes dependOnInheritedWidgetOfExactType()).
ScaffoldHandlerState keeps in a field the actions set by the various children, and supplies them to the app-bar.
a widget that creates the AppBar. In the build() method it gets the actions to be displayed calling ScaffoldHandlerState.of().
mixin ScaffoldChild on State, which applied to a widget gives it the ability to add actions to ScaffoldHandlerState.
Internally, ScaffoldChild executes ScaffoldHandlerState.of() in didChangeDependencies() (to add actions) and in deactivate() (to remove them).
I originally used initState() and dispose() but this did not handle the case where a ScaffoldChild changes position while not being permanently removed from the widgets tree.
The problem I encountered is that ScaffoldAppBar.build is executed before ScaffoldChild.didChangeDependencies, so when the app-bar is created, ScaffoldChild still has to put its actions in ScaffoldHandlerState.
The curious thing is that this problem is due to the simple linear order in which ScaffoldAppBar and ScaffoldChild are inserted in the page: if instead of a top app-bar I want to create a bottom app-bar, the problem is not there because ScaffoldChild.didChangeDependencies would run before ScaffoldAppBar.build.
As a workaround to overcome the problem, I have inserted in ScaffoldChild.didChangeDependencies a call to scaffoldHandler.setState scheduled by WidgetsBinding.instance.addPostFrameCallback(): thus, after the actions have been inserted in ScaffoldHandler, the app-bar is updated with the new actions.
However, this solution seems like a hack to me.
In stackoverflow I see a lot of problems solved with addPostFrameCallback + setState, and sometimes that solution avoids really understanding where it goes wrong; I am interested in understanding if there are better solutions because my purpose, as well as practical, was to better understand the lifecycle of widgets.
Is there a better solution?
This is my code:
DartPad or Gist
(I tried to shorten it as much as possible, but sorry if it's not really short)

What are dependencies of a state in flutter

I am trying to understand the method didChangeDependencies and according to the definition
It is Called when a dependency of this State object changes.
what do they mean by this. My guess is when properties in the state you manage per screen change. Am I right. Please I would love to understand better.
Try to think of it the same as initState but just a little later.
initstate is called before the state loads its dependencies and for that reason no context is available and you get an error for that if u use context in initstate. However, didChangeDependencies is called just few moments after the state loads its dependencies and context is available at this moment so here you can use context.
In case BuildContext.dependOnInheritedWigetOfExactType called, or in case the widget is been moved inside of the element tree, didChangeDependencies will is always called.

A better architecture than passing callback functions to children Widgets

I'm building my first Flutter app, in which I need to refresh a list of data, and every component has some modifiers.
This is the basic architecture.
A big list of data (about 5000 rows) is periodically refreshed from an API inside a RefresherWidget (which is a StatefulWidget that holds the list), and then passed along to the children.
Every RowWidget has a Switch (and Dialogs too) that modifies the data it represents.
Currently, the methods to modify the list are in the RefresherWidget, so I'm passing them as callback functions inside every children until reaching the onChanged callback of the Switch.
But I don't think it's a very clean solution, and I don't know how to implement a better one: I've tried thinking about passing these methods inside an InheritedWidget that stays between RefresherWidget and ListViewWidget, and referencing them using the of function, but I don't know about the perfomance hit I would get if the InheritedWidget gets rebuild.
Also, Streams and BLoCs seem very complicated for what I need to do.
How do you guys usually approach a problem like this?
This is definitely a situation for InheritedWidget or BuildContext in general.
I've tried [...] InheritedWidget [...] but I don't know about the perfomance hit I would get if the InheritedWidget gets rebuild.
You don't have to fear anything. InheritedWidget is built for this exact purpose.
Obtaining the InheritedWidget is very performant (O(1)). And only widgets that depends on the value gets rebuilt – which is optimal too.