Sup reader!, this is the second chapter in the series of flutter assuming that you have already setup your flutter editor now let's go...
If you haven't read the previous blog about introduction to flutter I strongly recommend to read it before reading this one.
Flutter is Google’s UI toolkit for crafting beautiful, natively compiled iOS and Android apps from a single code base. To build any application we start with widgets – The building block of flutter applications. Widgets describe what their view should look like given their current configuration and state. It includes a text widget, row widget, column widget, container widget, and many more.
What's a widget in flutter 🤔?
Widgets are the central class hierarchy in the Flutter framework. A widget is an immutable description of part of a user interface. Widgets can be inflated into elements, which manage the underlying render tree. Widgets themselves have no mutable state (all their fields must be final).
hunnnn, What are the types of widgets in flutter?
There are broadly two types of widgets in the flutter:
Stateless widgets is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely.
Stateful widgets are sensitive to what happens within its boundaries and gets rebuilt when a state change is detected. Conversely, Stateless widgets are not state sensitive and remain static throughout its life cycle.
okay, now you know you what a widget is, so what's next?
How do we write widgets in flutter ?
1. Write a stateless widget
class School extends StatelessWidget {
const School({ Key key }) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: const Color(0xFF2DBD3A),
child: Text("My school is Rwanda Coding Academy")
);
}
}
This will render a simple screen with a text My school is Rwanda Coding Academy
Well that was short and simple right?
2. Write a stateful widget
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Let's see magic happening 😂
As you can see from the above image, whenever we click the button at bottom the number of times that we have clicked increases by one.
wooh, in a stateful widget you got to write a bit more lines than in stateless widgets. In a stateful widget you've got to add some more components. Well, a stateful widget is a bit complicated compared to stateless widget.
Let's talk more about a statefull widget.
First of all being a stateful widget that means that it has a mutable state. The state is information that can be read synchronously when the widget is built and might change during a widget’s lifetime. It is the responsibility of the widget implementer to ensure that the State is promptly notified when such state changes, using the State.setState
method.
Here are some few concepts that you'll need to know about a stateful widget.
The concept of a state
- The data used by the widget might change
- The data can't be read synchronously when the widget is built. (All state must be established by the time the build method is called).
Take a close look on our stateful widget, probably you have recognized that MyHomePage
class is separate from _MyHomePageState
😕 Why is that so?
The simple answer is that it's because of perfomance 🤗. How ?
- Widgets are immutable. Since StatefulWidget extends Widget it therefore must be immutable too. Splitting the declaration into two classes allows both StatefulWidget to be immutable and State to be mutable.
- Widgets are instantiated using the syntax
new MyWidget()
. If we merged both classes into one,new MyWidget()
would reset all the properties of the state every time its parent update.
As for the further explanation of class _MyStatefulState extends State<MyStateful>
That is because the State class can access to it's Stateful part using the this.widget field. The generic is here to make that field of type MyStateful instead of just StatefulWidget. As you may want to access MyStateful properties.
Woww, clear now 🤗.
Lifecycle of a stateful widget
Hey, take a note on this !!!
1. createState()
When Flutter is instructed to build a StatefulWidget, it immediately calls createState(). This method must exist.
2. mounted is true
When createState creates your state class, a buildContext is assigned to that state. buildContext
is, overly simplified, the place in the widget tree in which this widget is placed. All widgets have a bool this.mounted
property. It is turned true when the buildContext is assigned. It is an error to call setState when a widget is unmounted.
3. initState()
This is the first method called when the widget is created (after the class constructor, of course.) initState is called once and only once. It must call super.initState()
4. didChangeDependencies()
This method is called immediately after initState
on the first time the widget is built.
5. build()
This method is called often. It is required, and it must return a Widget 🤗.
6. didUpdateWidget(Widget oldWidget)
If the parent widget changes and has to rebuild this widget (because it needs to give it different data), but it's being rebuilt with the same runtimeType
, then this method is called. This is because Flutter is re-using the state, which is long lived. In this case, you may want to initialize some data again, as you would in initState
.
7. setState()
This method is called often from the framework itself and from the developer. Its used to notify the framework that data has changed
8. deactivate()
Deactivate is called when State is removed from the tree, but it might be reinserted before the current frame change is finished. This method exists basically because State objects can be moved from one point in a tree to another.
9. dispose()
dispose() is called when the State object is removed, which is permanent. This method is where you should unsubscribe and cancel all animations, streams, etc.
10. mounted is false()
The state object can never remount, and error will be thrown if setState is called.
Woww, wowww thanks for reading to this far 🔥 from now you can go ahead and start playing with flutter changes 😂 try writing as many as you can.
for more widgets please head to Flutter
Top comments (6)
wow, such amazing masterpiece
I'm learning from your posts. Can't wait for another one @dmutoni
thank uu
Woow! Nice article @dmutoni ☺️
thank you 🔥
thank u too for reading 🤗