Book
  • Introduction
  • Welcome !!
  • Chapter 1: The mobile ecosystem
    • Fragmentation is the devil
    • There is more than one type of mobile app
    • ... more than one type of app
    • ... one type of app
    • Under pressure (ee da de da de) !!
    • Further reading!!
  • Chapter 2: Let's start with design thinking
    • A taste of design thinking
    • The five steps
    • Design for everybody
    • Accessibility in mobile apps
  • Chapter 3: Give me a context and I will give you an app
    • Users
    • Personas? Users ? What is the difference?
    • Please, help me to model the context
    • The context canvas
  • Chapter 4: Powerful models
    • Data architecture is the foundation of analytics
    • From data to information and knowledge
    • Information/Knowledge in our mobile ecosystem
    • Questions to ask yourselves when building and classifying questions
    • The visualization-data map
    • On the scene: describing how personas interact with your app
  • Chapter 5: A GUI is better than two thousand words
    • 'Good to Go:' Let's explore the Design Systems
    • Designing GUI Mocks
    • No prototype... no deal
  • Chapter 6: About mobile operating systems ... and other deamons
    • The Android OS ... son of LINUX
    • iOS son of Darwin? or is it iOS son of UNIX?
    • Kernels
  • Chapter 7: Yes, software architecture matters !!
    • Self-test time
    • About design and design constraints
    • Architects' mojo: styles and patterns
    • What you need is a tactic !!
    • Self-test time 2 (for real)
    • Further reading
  • Chapter 8: Finally... coding
    • MVC, MVVM, MV*, MV...What?
    • Programming models: the Android side
    • Hello Jetpack, my new friend... An Android Jetpack Introduction
    • Programming models: the iOS side
    • Controllers and more controllers
    • Flutter son of... simplicity
    • Programming models: Flutter?
    • Flutter: State matters... Let´s start simple
    • Flutter: State matters... Complex stuff ahead
    • Micro-optimizations
  • Chapter 9: Data pipeline
    • Generalities data pipelines
    • Data storage types
    • Types of data pipelines
  • Chapter 10: Error Retrieving Chapter 10
    • Eventual Connectivity on Mobile Apps
    • How to handle it on Android
  • Chapter 11: The jewel in the crown: Performance
    • As fast as a nail
    • Memory bloats
    • Energy leaks
    • Final thoughts
  • Chapter 12. Become a performance bugs exterminator
    • Weak or strong?
    • Micro-optimizations
    • The single thread game !!
    • Using multi-threading like a boss !!
    • Caching
    • Avoiding memory bloats
    • Further readings
Powered by GitBook
On this page
  • Everything is a widget
  • Your own widgets
  • Bonus: Expecting the future
  1. Chapter 8: Finally... coding

Programming models: Flutter?

PreviousFlutter son of... simplicityNextFlutter: State matters... Let´s start simple

Last updated 1 year ago

(By Sergio Guzmán)


This is based on the .

Everything is a widget

Flutter has one core principle: everything is a widget. There is a readily available widget for pretty much everything you will use in your app, including:

  • Stylistic elements like fonts and colors

  • Layout elements like margins and paddings

  • Graphic components like buttons, lists, images, menus, etc

  • And... animations, user interaction, etc

Lets take a look at a really simple example using the MaterialDesign dart library (just to have a runApp method implemented). This is our main method, that just renders a text:

import 'package:flutter/material.dart';

void main() => runApp(
      Text(
        'Hello I am just a text',
      ),
    );

We can encapsulate our text inside a layout widget (like MaterialApp for instance) to recognize that we have an available space on the screen and thusly change the style of the component:

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: Text(
      'Hello I am just another text',
      style: TextStyle(
        color: Colors.amber.withOpacity(1.0),
      ),
    )));

Now let´s make it more beautiful by using a default Scaffold widget from the material design lib and adding a FloatingActionButton of course.

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("My app"),
        ),
        body: Text(
          'Hello I am just a text',
          style: TextStyle(color: Colors.blue.withOpacity(1)),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
        ),
      ),
    ));

Finally, we´ll give it some layout order too by centering the text in a Container:

import 'package:flutter/material.dart';

void main() {
  return runApp(MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: Scaffold(
      appBar: AppBar(
        title: Text("My app"),
      ),
      body: Container(
          child: Center(
              child: (Text(
        'Hello I am just a text',
        style: TextStyle(color: Colors.blue.withOpacity(1)),
      )))),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
      ),
    ),
  ));}

The downside of using widgets is the nesting hell generated by encapsulating a widget, inside another widget, inside another widget, and so on... To make your code look a little bit nicer during this "widget composition", class-oriented programming comes to the rescue

Your own widgets

There are two types of widgets you should look out for: StatelessWidget and StatefulWidget. When you define your own widgets, you will extend from one or the other, depending on your needs.

You want something static? The StatelessWidget is meant for static things, like text, images, fonts, paddings and so on.

import 'package:flutter/material.dart';

class MyView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

Your screen will be changing over time? Go with Stateful

import 'package:flutter/material.dart';

class MyView extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyViewState();
}

class _MyViewState extends State<MyView> {

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

The StatefulWidget will likely be calling the setState method to repaint the widget tree, depending on the state of your widget. These widgets are used a lot for handling user interaction.

When creating a custom widget, always override the build method, which returns a widget tree to be painted in your app.

So how would this look for our app? Let´s put the body of the MaterialApp widget inside a StatefulWidget and add a counter for the state.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState 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('My App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button $_counter times',
              style: TextStyle(color: Colors.blue.withOpacity(1)),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

If you notice, whenever we press the FAB button a new funtion is called (_incrementCounter), that modifies the counter variable.

State management can be tricky, and that´s why we have a whole new section dedicated for this coming up!

Bonus: Expecting the future

Much like in JavaScript, Flutter has an implementation for creating asynchronous tasks and waiting for them: a future. A future is the result of an asynch task that has two possible states: uncompleted (the task is still in progress) and completed (the task ended). For a future to be fulfilled there are two possibilities:

  • Completed with a value: Future<T> will return a value of type T

  • Completed with error

Future<String>  createOrderMessage() async {
  var order = await fetchUserOrder();
  return 'Your order is: $order';
}

Future<String>  fetchUserOrder() =>
    // Imagine that this function is
    // more complex and slow.
    Future.delayed(
      Duration(seconds: 2),
      () => 'Large Latte',
    );

Future<void>  main() async {
  print('Fetching user order...');
  print(await createOrderMessage());
}

Notice the use of await to wait for the result of a future and async to declare a function that will have awaits in its code. Without these two, when you call a future your code won´t wait for a result.

Also... for error handling use a try-catch

try {
  var order = await fetchUserOrder();
  print('Awaiting user order...');
} catch (err) {
  print('Caught error: $err');
}

Futures are important when doing blocking operations (I/O mostly) and making requests to external services (APIs)

So yeah,everything is handled with a widget. Look at this to get an idea of all the widgets you can use with Flutter.

Nested hell is real, it's the reason why some devs dislike Flutter. Take a look at , and to get an idea about it

Here´s an example from :

awesome catalog
this Reddit´s post
this Github issue
the devs at Flutter
official docs
Flutter basic text
Flutter basic styled text
Flutter scaffold text
Flutter scaffold center text
Flutter stateful text