DEV Community

Ludovic Taffin
Ludovic Taffin

Posted on • Updated on

Flutter - Understand your first app

The original post is here : https://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());  
}
Enter fullscreen mode Exit fullscreen mode

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

void main() => runApp(new MyApp());
Enter fullscreen mode Exit fullscreen mode

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'),  
          );  
  }  
}
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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.
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (4)

Collapse
 
zimlearn profile image
Dr Abstract • Edited

I feel sorry for Flutter users. I mean no disrespect but... that is a ridiculous amount of code for a basic app. It is way too verbose with words coming out of no where (although you did a good job writing about it). Some of that might be Dart... some of it might be Flutter. No matter how you cut it... this code could have been 1/4 the size and still do what it is supposed to do. Here is a comparison video youtube.com/watch?v=V66OpDIFCvE. It may be that Flutter can do things in a shorter way than we can on the Canvas in JS... but in all the examples I have looked through that has not been the case at all. Cheers.

Collapse
 
zimlearn profile image
Dr Abstract

Thank you Ludovic - I thought I might have upset you and was worried. Anyway - all the best.

Collapse
 
drumor profile image
Ludovic Taffin • Edited

Hello!

Not at all :-) I found your comment interesting. I agree that some things are way too "verbose". As I start learning Flutter, i'll probably discover why they decide to do it like that. I had no time to see the video but will definitely take time to do that!

In a more general point of view, i like interaction like yours. It's good to have an external point of what is good and what is not. Thank you!

All the best!

Thread Thread
 
zimlearn profile image
Dr Abstract

Indeed, there are bound to be reasons why they have done things the way they do. And often, once these are learned, they become obvious and no problem... still, I do have my doubts. The video clearly shows some issues, regardless of reasons. Perhaps maintaining some sort of reporting hierarchy as they do really adds up the code - we are at 25% their code... that is a lot of complex infrastructure and, in my mind, not easily coded by anybody other than serious developers... yet Google is pushing the platform at front end-developers who are often on the design fence. I guess it will be up to people to decide in the long-run.