Once we’ve installed Flutter, and built the test app, we now want to look at what is in the source code, to get an idea of how we’re going to be building applications. For such a simple app, there is actually, quite a bit going on, but it’s simple enough to understand.
Let’s look at the code in sections – and see how it relates to one another. You may want to bring up your entire source code to see how it all fits together, or you might want to just go through ours. The comments in their source code do a pretty good job of explaining what is happening, but I’ve tried to add some to it.
import 'package:flutter/material.dart';
Notice, right off the bat we’re importing a library. Specifically the materials library. Material
was built by Google to handle their UI and provides a consistent UI for us to use, and one that if familiar to end users. For us to use it, we simply import it.
Likewise, if we need to import other libraries, we have knowledge of how to do that.
void main() {
runApp(MyApp());
}
Just like in C++ and Java, we have a main function. You’ll find that a lot of the code looks similar to C++/Java, but there are differences. It is going to call the runApp() function, which creates an anonymous object of type MyApp, which we will see in just a minute.
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
This is the entire class which we created just a few lines ago. This will set up our application.
We override the regular build method, to provide context, provide a default title, and define the theme. We can easily change primarySwatch, color palette, by instead of using Colors.blue
, choosing one of the many other colors that are available to us.
If you type in Colors.
in VSC, you will get a large variety of colors to pick from, and samples of what the color will look like. This is a quick and easy change.
Likewise, you can change the default title of the MaterialApp
which you are creating and returning.
Notice, that you define a home screen, which is another class that will need to be defined and returned… more on that in just a second.
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
The MyHomePage
class extends the SatefulWidget
class. This is important, because it means that is is also stateful, i.e. it retains information about the widget. In this case, it is just the title, which is final, so that it cannot be changed.
Notice that it creates the state based on another class, _MyHomePageState
.
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
This piece of code is used to identify the counter, and remember that value. Because of that, it also has the event handler.
The event handler _incrementCounter()
, generally speaking, is used to increment _counter
with the _counter++
command.
Notice that within _incrementCounter(
), there is a call to setState()
where an anonymous function is called. This anonymous function is where the actual incrementing, by calling the _counter++
command occurs. The setState()
function is used to let Flutter know that something has changed in the state of the application.
If you changed _counter without calling setState(), then the build method would not be called again, and nothing would appear to happen as it wouldn’t be updated in the UI.
@override
Widget build(BuildContext context) { ... }
If you go back to class MyApp extends StatelessWidget you notice a call to this Widget, which is overrides the build method here.
Within this widget build method, you will return Scaffold
which is an object of items for the widget such as the appBar (title bar), and the body. The body will contain the contents of the app, such as the text areas and the button as is seen in the simplified example below.
return Scaffold(
appBar: AppBar( /* ... */ ),
body: Center( /* ... */ )
);
The appbar is defined as:
appBar: AppBar(
title: Text(widget.title),
),
In this code, we are setting the title. This title was initially set when you created the MyHomePage object, that was created by the App.build method. So title is not just coming from no where.
body: Center( /* ... */ )
Here we are going to define the body. We are using Center() and passing in data to it. Center is a layout Widget which helps define how and where we are going to layout the content.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ /* ... */ ]
floatingActionButton: /* ... */
)
Within Center, we pass in a child, which is another layout widget – Column. This once again helps us lay out our content.
Column has various properties to control how it sizes itself and how it positions its children. In this example mainAxisAlignment is used to center the children vertically.
The children specify what components will be shared on the screen. This is an array of widget elements.
Finally, we have a floatingActionButton – which is what we press to increment the counter. We’ll look at that in a minute.
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
Here we are taking a closer look at the children of our Column. This is what is defining what will be display. In this case, two Text objects.
The first one is a label. Notice that it is within the single quotes. Note: Double quotes can also be used.
The second Text object looks similar, however, there are two differences.
First, the value in the single quotes is a $_counter
. If you remember from earlier, _counter
was an instance variable which can is being used to store how many times we’ve clicked on the button. By putting a $ (dollar sign) in front of it, we are defining that it is to use the variable and not a literal string.
The second difference is that we define the optional style. This way, we are making it as a headline, and thus in this case the text will be larger. We do that by getting the Theme, based upon the initial context, and then getting one of those potential values.
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
)
This floatingActionButton is a fairly simple component. It takes an object of FloatingActionButton, which takes several items in it’s constructor.
That being, what to do when the item is pressed (or clicked) – in this case it calls the _incrementCounter
method defined earlier in _MyHomePageState
. It also defines a tool tip, and uses an existing icon.
Diving into the Sample Flutter App’s Source Code was originally found on Access 2 Learn