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)
Related
I have a DefaultTabController that is getting longer and longer in code. As a beginner, I see I might miss some class / oop knowledge here.
I want to move its children to new files. I already have Widget TabContent1 and Widget TabContent2 in the same class, but how can I move these widgets to new files? The problem is that they both load values of TextEditingControllers on the TabController level. Moving the two Widgets breaks the reference to these TextEditingControllers. How can I refer to those from the newly created classes?
Update: In addition. As suggested by Ivo, I can put all references in the constructor of my new class. But I have a lot of global controllers and variables in the top level class. Also need to bind to the events happening in my new class and have to emit those back or so. It feels more efficient to keep my logic, but only move some of it to sub-classes or so. I feel like the solution should be more in oop/class logic, implementing or extending them
I have a flutter application which uses a MultiProvider widget at the root of the widgets tree.
The problem is, I need to add a ChangeNotifierProvider to the MultiProvider widget, but later because I can't create it at the beginning (well I could but it makes more sense to do it later *).
How am I supposed to do?
(* for more details about why I would like to create the ChangeNotifierProvider later: The associated ChangeNotifier represents a bluetooth connection that will not be available at the start of the application.)
In these situations I create Provider with object which have some initial values and later I change initial values to actual.
to propagate properties or methods down the tree in Flutter widgets, I usually use the Provider package with Provider.of<someClass>(context).doSomething(). Now, I also have normal class based components that do something, e.g File handling or so.
Can I somehow inject or use my Provider class in normal class components, too?
I assume its not possible the usual way, because Provider needs a context, but is there another way?
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((){})
I'm developing an application consisting of 3 modules.
The users can start a web chat (implemented as a widget) and then navigate through the modules. I would like the web chat widget to be kept during the navigation.
I've added a static field in the widget containing the current instance, but it is only persisted while I remain in the same module. If I change module the widget is re-created by scratch.
Is there a way to define an object with application scope?
A better solution (than keeping global state) would be to use Dependency Injection and inject your widget to all relevant views.
Using gin it'd look like this:
#Singleton
public class CommonWidget {
}
public class View1 {
#Inject
public View1(CommonWidget widget) {
}
}
public class View2 {
#Inject
public View2(CommonWidget widget) {
}
}
Now, widget in View1 and View2 point to the same widget.
The problem is that you have to be careful when using this widget - remember that you can only add a widget once to the DOM, so before adding it in View2, you have to remove it from View1.
I think that instead sharing the widget this way, you should either share the messages between two chat widgets or better yet, move the chat widget "above" the views (either literally or figuratively), so that there's only one instance.
Of course, there are more steps to setting up gin, but you can read about them in the docs.
You can create any widget in your entry point class (#onModuleLoad), and then reference/call this widget from any activity that needs it. However, I would only recommend this solution in two cases:
A widget is a container for the entire application or part of the application (e.g. top menu, main panel) that is always visible on a screen, so you don't add/remove it from UI - you simply call it to change its state.
A widget is a popup panel or similar (e.g. confirm dialog, error notification, etc.), so reusing it in different activities/views does not cause any problems.
You may want to take a look at Activities and Places design pattern. It supports most typical navigation scenarios, where you move from one Activity/View to another within the same app (container) widget.
UPDATE:
This is a quote from GWT docs about the use of multiple modules:
If you have multiple GWT modules in your application, there are two
ways to approach loading them.
Compile each module separately and include each module with a separate
tag in your HTML host page.
Create a top level module XML
definition that includes all the modules you want to include. Compile
the top level module to create a single set of JavaScript output.
The
first approach may seem the easiest and most obvious. However, the
second approach will lead to much better end-user performance. The
problem with loading multiple modules is that each module has to be
downloaded separately by the end-user's browser. In addition, each
module will contain redundant copies of GWT library code and could
possibly conflict with each other during event handling. The second
approach is strongly recommended.