Flutter Walkthrough - Understand your first app

The original post is here : drumor.dev/posts/flutter-first-app-analyze

Hello, So I recently restart my learning of Flutter. After the installation of flutter with Android Studio (see doc), I create my first default project. Let see how does that works.

Most of the Dart code you'll use and edit is in the lib folder. Another important part of a flutter project is pubspec.yaml file.

lib/Main.dart

All the app is here. It starts with this:

void main() {  
 runApp(MyApp());  
}

As you can use the narrow notation , you could also write the main as this :

void main() => runApp(new MyApp());

This looks like a classical main code. It runs the app that is defined after:

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.
              //
              // 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 simply save your changes to "hot reload" in a Flutter IDE).
              // Notice that the counter didn't reset back to zero; the application
              // is not restarted.  
              primarySwatch: Colors.blue,  
          ),  
          home: MyHomePage(title: 'Flutter Demo Home Page'),  
          );  
  }  
}

So the app is defined and extend StatelessWidget. In Flutter, almost everything is a Widget. In this case it's a widget without state. So it keeps no data. A build method is defined which is a sort of constructor of MyApp object. All widget have a build method. The method describes how to display the widget in terms of other, lower level widgets. This example creates a Material app. Material is a visual design language that is standard on mobile and the web. Flutter offers a rich set of Material widgets. A title, a theme and a home page are defined.

Let's now have a see on the MyHomePage object:

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();
}

MyHomePage is a stateful widget. This means that, during the lifetime of the widget, a state that might change is maintained. Implementing a stateful widget requires at least two classes:

  1. a StatefulWidget class that creates an instance of
  2. a State class.

The StatefulWidget class is, itself, immutable and can be thrown away and regenerated, but the State class persists over the lifetime of the widget.

Here is the State class _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.
    );
  }
}

We discover some interesting elements :

  • First we have a private (the _ indicates this ) variable counter thatwill store the count of hit:

    int _counter = 0;
    
  • Secondly, we get a private method, called _incrementCounter, that ... increment the counter (Incredible! Right?!) by calling the setState method from Flutter framework. This method call (by default) the build method defined after.
  • And last but not least, the build method that "simply" return a Scaffold widget. A scaffold widget is a layout where we have a top bar (Blue because the theme defined use the color blue), and a body. Here, the body is defined as a center layout that content a child Column and a floating button. The column widget is also a layout and represents a column (No way!!). It takes a list of children that are display one under the other (like a stack). In our case, there is two elements in the column, a default text and the display of the counter. The floating button is simply a button floating on the bottom right of the screen. This button has a OnPressed callback that runs _incrementCounter when the button is pressed.

Pubspec.yaml

This is the configuration file of a flutter project. This lets you configure the name and description of the project, the SDK used, the dependencies of the project and others specifications. We will see later that if you wanna use assets (like pictures) in your project, you'll have to define it in this file.

Did you find this article valuable?

Support Drumor's Blog by becoming a sponsor. Any amount is appreciated!