Why Container and Column are not const flutter? - flutter

Please see the question above. I looked the documents, but didn't find any answers.

It depends on the child/ children if they don't have static value it can't be const. if the have hardcoded or static values then it must be const

Why do we need to use const widgets in flutter?
It is recommended to use const constructors whenever possible when creating Flutter widgets. The reason is the performance increase since Flutter can save some calculations by understanding that it can reuse that widget from a previous redraw in the current one since it is a constant value.
Flutter has a special treat for when the instance of a widget doesn't change: it doesn't rebuild them.
Consider the following:
Foo( child: const Bar( child: Baz() ), )
In the case of the build method being called again (setState, parent rebuild, Inheritedwidget...), then due to the const for Bar subtree, only Foo will see its build method called.
The bar will never get rebuilt because of its parent because Flutter knows that since the widget instance didn't change, there's nothing to update.
Why can't we make a Container widget and Column widget const?
You cannot make const a Container as the Constructor of Container is not const that's why it won't let you do it.
This is allowed in the form of making the children const. Allowing const on the children means they will not rebuild if they are not dynamic.
Flutter doesn't rebuild widgets that are marked created through const constructor and the main part of the flutter widgets supports const constructors. Except for Column and Row and other multi-child layout widgets.
Do we really need to make multi-child layout widgets const?
The Column/Row themselves do not need to be const as they're only for laying out the widgets, it's the children that need to const. The same behavior applies to the rest of the Multi child layout widgets.

These might be for lots of reasons. Instead of listing all of them here. I will show you how to explore each one of them on your own so that you can orient your investigations based on your needs. Below, are the steps I went through to figure out why the container is non-const. (you can do this with any other Widget or constructor)
Explore the source code
Open the fuller package (in VSCode): [flutter_location]/packages/flutter/lib/src/widgets/container.dart
Run flutter pub get
Look for the Container constructor
Add the const keyword in front of it
All elements that prevent the Container from being a const constructor, quite a few, will show errors!
To explore multiple widgets at once just open the entire folder [flutter_location]/packages/flutter. Then run flutter pub get.

Related

Why is dart forcing me use const

I have this piece of code that intend to use in a stateless widget in flutter.
const String default_question = 'the question';
class Trial {
final String question;
const Trial.standard() :
question = default_question;
}
I use it like this:
final Trial _trial = const Trial.standard();
And this works. But it doesn't work without using const. And I want to understand why const is neccessary here. Because I plan on using a constructor that is not constant in the future.
-----------EDIT---------------
So I had a deeper look into the problem. My IDE linked the error to sauce. Which made me realise that the problem had nothing to do with trial but with the constructor for the stateless widget that I was using. The constructor that I had for the stateless widget was a constant costructor, I think that that is a default configuration voor creating a new stateless widget with my IDE. So I just removed the const keyword there and now I can declare variables in that widget that are not constant.
I'm not sure if a non constant constructor for a stateless widget is bad practice in flutter, but for now it makes sense to me.
cosnt marked widgets or variables are built only once in flutter framework which helps in performance improvement.
And this is done by a packages flutter_lints which is added in pubspec.yaml by default in latest flutter versions. You can check docs at given at flutter official website.
If you don't want to use this thing, simply remove the package from pubspec.yaml
Cheers!

Methods vs separate classes for widgets in Flutter?

I heard a lot about "flutter method-widgets is considered anti-pattern". But why? Elements don't care about widgets' parameters (equal or not). Only const widgets save rebuilds. So why do I have to separate them to relatively verbose classes, when I could just
Widget _buildMe() => Container() // here is some widget, which depends on other params (so it cannot be const)
inside my StatelessWidget class.
Update: I also assume that methods don't depend on InheritedWidget. In that case it's obvious, that they should be separated.
It's an anti-pattern, because in some cases it leads to unnecessary rebuilds (depending on Inherited widget for example). But in general you can use it, if you use it wisely (2-3 methods in class don't make any harm).

Meaning of the term .of() in flutter

So I was wondering about the Command I use when I close an AlertDialog:
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(context).pop();
},
),
What does .of() exactly do? I could not find anything in the flutter dev documentation (Probably because I was missing the correct search term)
Can anyone explain what happens there?
In the Flutter SDK the .of methods are a kind of service locator function that take the framework BuildContext as an argument and return an internal API related to the named class but created by widgets higher up the widget tree. These APIs can then be used by child widgets to access state set on a parent widget and in some cases (such as Navigator) to manipulate them. The pattern encourages componentization and decouples the production of information related to the build tree with its consumption.
In addition to Navigator.of (returns a NavigatorState) there are:
Theme.of (returns a ThemeData containing the ambient theme settings)
MediaQuery.of (returns a MediaQueryData containing information computed about the device screen size)
Directionality.of (returns a TextDirection containing information about text display)
Of course Flutter has non-specific methods for looking up parent widgets from the build context:
context.findAncestorWidgetOfExactType<T extends Widget>()
context.findAncestorStateOfType<T extends State>()
context.findRootAncestorStateOfType<T extends State>()
so Theme.of(context) is really just a static shorthand for context.findAncestorWidgetOfExactType<Theme>().data and Navigator.of(context).pop() is really just a shorthand for context.findAncestorStateOfType<NavigatorState>().pop()
From the documentation of the Navigator class,
Although you can create a navigator directly, it's most common to use the navigator created by the Router which itself is created and configured by a WidgetsApp or a MaterialApp widget. You can refer to that navigator with Navigator.of.
As a general rule, any time you see something along the lines of Classname.of(someObject) in an OO language, .of is a builder that returns an instance of Classname from someObject.

How does `build` occur from root to leaves in Flutter?

I've tried tracing through the source to answer this but I get a little lost in the Flutter machinery. We pass runApp a Widget, which becomes the root widget of our app. That widget must implement build, which returns a Widget.
Does Flutter just use simple recursion to call build on that returned Widget, and so on, for the Widget returned by each subsequent child's build method?
While recursing, and it encounters a StatelessWidget, does Flutter do a type check to call createState instead of build, and then perform an extra step, calling build on the State that createState returns?
How does the recursive / chain of calls to build methods stop? For example, the Text widget has a build method that returns a RichText widget, which is a MultiChildRenderObjectWidget. Does Flutter again do type checking here and stop calling build and instead invoke createElement, which in the end generates the elements for the Element tree?
It is more complex than a simple recursion.
You can read more about the build and render process of a widget here
https://api.flutter.dev/flutter/widgets/WidgetsBinding/drawFrame.html
While the widgets are inmutable, Elements are the instantiation of them. So while StatelessWidgets and StatefulWidgets are recreated in each build, Elements are updated in the tree.
The StatefulWidget is managed by StatefulElement that keeps the state instance in its instance, so it persits while the StatefulWidget is rebuilt
The docs has a very good explanation of what is an Element too:
https://api.flutter.dev/flutter/widgets/Element-class.html

How do I add ScrolledWindow support to a custom Widget in GtkMM?

I am writing a custom widget for Gtkmm that is supposed to display a huge dataset (imagine something like a 4096x256 character datasheet).
Mostly for reasons of elegance, but also for a possible usage in a Glade/Gtk-Builder editor, I want this widget to support ScrolledWindow natively, that is, once it is set as the child of ScrolledWindow, it is recognized as a scrollable widget, allowing to set horizontal and vertical Adjustment objects on it, which it can subsequently tamper with.
It appears to do so, I need to do something like this in the constructor of my widget:
// get Gtk C type from wrapper class
GtkWidget* gwidget = this->gobj();
// imagine code here that magically creates a gobject signal,
// that we can catch in C++.
// this is actually the part which I don't know how to do.
guint my_signal = magic_way_to_create_this_signal(
&MyClass::rainbow_unicorn_signal_handler);
// make ScrolledWindow recognize this window as scrollable
GTK_WIDGET_GET_CLASS(gwidget)->set_scroll_adjustments_signal = my_signal;
Later on, the signal emitted by ScrolledWindow when the widget is added needs to be caught by my Widget through a signal proxy method or something? I have no idea.
How can I do this?
The 'magic_way_to_create_this_signal' is g_signal_new(). You call it in your widget's my_widget_class_init() function which is part of the GObject way of defining a class. I'm not exactly sure what the equivalent is in Gtkmm.
See also the footnote in the GTK docs, where it is explained why making a widget natively scrollable is such a hassle.
You could also put your widget into a Gtk::Viewport which adds scrolling capabilities to its child widget.