Flutter Default Application Project
All of the application code resides in one file: ‘main.dart’ in the ‘lib’ folder.
Remember that Dart lets you declare multiple objects within a single file!
Introduction to Composition & Widgets
Widgets are the Building Blocks of your UI.Whenever we build a user interface in Flutter, it is composed of Widgets.
Putting your widgets together is called Composition.
Widget Tree
Unlike a Jigsaw, a widget can contain other widgets, in a tree structure, a hierarchy. This is often called a Widget Tree.Composition & Widgets in the Default Application
If you look at the next diagram, the Object/Widget tree is on the left and the UI is on the right. You can see how they correspond to each other. Note that in the object/widget tree, the blue objects are custom widgets and the orange objects are flutter widgets.Custom Widgets in Default Application
The blue objects in the diagram above. Although the default application contains many widgets, only two custom widgets were required to make it work:MyApp widget.
It is a custom widget for the entire application.MyHomePage widget.
It is a custom widget that contains the layout for the application, plus the application state (the counter).Other Widgets in Default Application
The orange objects in the diagram above. The rest of the widgets are from the Flutter widget library, already built for us.The blue object is the scaffold widget.
The red object is the app bar widget.
The green object is the center widget, which contains a column object, which contains 2 text objects.
The light blue object is the floating action button widget, which contains a ‘+’ icon.
MyApp Widget
The MyApp object is a StatelessWidget. It sets up a Material App that contains a MyHomePage widget. The MaterialApp widget is a built-in Flutter widget that servesas the container for your whole app and itsWidgets. It provides services that child Widgets may use, such as navigation, sizing, themes etc.
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
MyHomePage Widget
This is a stateful widget, more on these later. This widget holds the count as State (data) and it sets up the child objects in the ui:The center widget, which contains a column object, which contains 2 text objects:
‘You have pushed the button this many times:’
0
The floating action button widget, which contains a ‘+’ icon. When the user clicks on the floating action button, this increments the instance variable ‘_counter’ inside a the ‘setState’ method. Making a call to the ‘setState’ method tells Flutter that something has changed and the UI needs to be rebuilt, so it invokes the ‘build’ method in this widget, which redraws itself with the new counter value.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return new Scaffold(
appBar: new AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: new Text(widget.title),
),
body: new Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: new Column(
// Column is also layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug paint" (press "p" in the console where you ran
// "flutter run", or select "Toggle Debug Paint" from the Flutter tool
// window in IntelliJ) to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}