flutter tutorial

Contributed by: Kalyan Raman

Like the Linux or Windows operating system that controls your desktop or laptop, a mobile operating system or mobile OS is a software platform that helps other programs run on mobile devices. This platform is specifically designed to run on devices such as mobile phones, smartphones, PDAs, tablet computers and other handheld devices.

The operating system determines the functions and features available on your devices, such as thumbwheel, keyboards, WAP, synchronization with applications, email, text messaging and more.

Developing a mobile application is a complex and challenging task. There are various operating systems, and each one has a framework to develop a mobile application. In the case of Android, the native framework is based on the Java language, while that of iOS is based on Objective-C / Swift language. Developing an application that supports the Android and Apple operating systems, requires coding in two languages in different frameworks. FLUTTER can help reduce the effort and overcome this complexity.

Flutter is an open-source framework to create high quality, high-performance mobile applications across operating systems. It is a portable user interface (UI) framework for building modern native and reactive applications for the mobile, web and desktop.

Flutter’s framework is based on the Dart language. It enables high performance by rendering the UI directly in the operating system’s canvas rather than through the native framework. These frameworks range from a simple HTML-based hybrid mobile application framework (that uses HTML for UI and JavaScript for application logic) to a complex language-specific framework (that does the heavy lifting of converting code to native code). 

Even though Flutter is used to create beautiful and customizable widgets for high performance and outstanding mobile applications, it also has its advantages and disadvantages.

Advantages of Flutter

  1. Dart has a large repository of software packages which allow you to extend the capabilities of your application.
  2. Developers need to write just a single code base for both applications (Android and iOS). Flutter may even be extended to another platform in future.
  3. Flutter requires lesser testing. Given its single code base, we only need to write automated tests only once for both platforms.
  4. Flutter’s simplicity and capability for customization and extensions make it a powerful tool for faster development. 
  5. With Flutter, developers have full control over the widgets and their layouts.
  6. Flutter offers great developer tools, with amazing hot reload.

Disadvantages of Flutter

Notwithstanding the above advantages, Flutter has the following drawbacks −

  1. The developer has to learn the Dart language to write codes for Flutter.
  2. Modern framework tries to separate logic and UI as much as possible; however, the user interface and logic are intermixed in Flutter.
  3. Flutter is yet another framework to create mobile applications. Developers find it challenging to choose the right development tools in a hugely populated segment.

Flutter Widgets

The Flutter framework is based on the core concept of ‘everything is a widget’. Widgets are nothing but the building blocks of the Flutter app. Each widget is an immutable declaration of the UI. Widgets are the configuration or the instructions for different parts of the UI, and placing the widgets together creates the application.

For example – an architect creates a blueprint of a house, each element of the house like the walls, windows, doors are the widgets, and the house is the final application.
Based on the types of events, widgets are classified as stateless and stateful. Stateless widgets are the ones where the values do not change – for example, the image inside a photo frame; and the stateful widget is used when the values or objects change constantly.

In the above images, the dog inside the photo frame is static and will not change or move. Here the stateless widget is declared with one class, that is, one build or item to compose one UI.

A stateful widget is based on its configuration but can be dynamic; for example, the dog taking a selfie. Both the dog and its surroundings can change simultaneously, so this widget is mutable and can change over time. In such scenarios, Flutter creates two classes – the stateful widget class and the state class. The stateful widget class is rebuilt multiple times. When the widget values or surroundings of the dog change, the state class keeps changing. It creates multiple layers and constantly updates itself and provides the updated images to the stateful widget class.

Flutter Framework

Flutter is designed as an extensible, layered system. It exists as a series of independent libraries, each depending on the underlying layer. No layer has privileged access to the layer below, and every part of the framework level is designed to be optional and replaceable.

To the underlying operating system, Flutter applications are packaged in the same way as any other native application. A platform-specific embedder provides an entry point; coordinates with the underlying operating system for access to services such as rendering surfaces, accessibility, and input; and manages the message event loop. The embedder is written in a language that is appropriate for the platform: currently Java and C++ for Android, Objective-C/Objective-C++ for iOS and macOS, and C++ for Windows and Linux. Using the embedder, Flutter code can be integrated into an existing application as a module, or the code may be the entire content of the application. Flutter includes several embedders for common target platforms, but other embedders also exist.

At the core is the Flutter engine, which is mostly written in C++ and supports the primitives necessary for all Flutter applications. The engine is responsible for rasterizing composited scenes whenever a new frame needs to be painted. It provides the low-level implementation of Flutter’s core API, including graphics (through Skia), text layout, file and network I/O, accessibility support, plugin architecture, and a Dart runtime and compile toolchain.

The engine is exposed to the Flutter framework through dart:ui, which wraps the underlying C++ code in Dart classes. This library exposes the lowest-level primitives, such as classes for driving input, graphics, and text rendering subsystems.

Typically, the Flutter framework provides the developers a modern, reactive framework written in the Dart language. It includes a rich set of platform, layout, and foundational libraries, composed of a series of layers. Working from the bottom to the top, we have:

  • Basic foundational classes, and building block services such as animation, painting, and gestures that offer commonly used abstractions over the underlying foundation.
  • The rendering layer provides an abstraction for dealing with layout. With this layer, you can build a tree of renderable objects. You can manipulate these objects dynamically, with the tree automatically updating the layout to reflect your changes.
  • The widgets layer is a composition abstraction. Each render object in the rendering layer has a corresponding class in the widgets layer. In addition, the widgets layer allows you to define combinations of classes that you can reuse. This is the layer at which the reactive programming model is introduced.
  • The Material and Cupertino libraries offer comprehensive sets of controls that use the widget layer’s composition primitives to implement the Material or iOS design languages.

The Flutter framework is relatively small; many higher-level features that developers might use are implemented as packages, including platform plugins like the camera and web view, as well as platform-agnostic features like characters, HTTP, and animations that build upon the core Dart and Flutter libraries. Some of these packages come from the broader ecosystem, covering services like in-app payments, Apple authentication, and animations.

How Flutter works?

Now we know what a widget is, and what the flutter framework is, let’s understand how flutter works.

As you all know, everything in Flutter is a widget. Widget is an immutable description of a part of a UI. There are 3 components which Flutter depends upon – 

  1. Widget
  2. Element
  3. Render Object

Widget is something that holds the configuration that you provide to the UI, for example, padding widget  (space between 2 square boxes/ lines). To avoid cluttering inside the mobile layout, between the images or text, one needs to provide padding. Once the details of padding are provided, the widget creates a hierarchy & child element that stores the details. That is the padding value(location and space required) and the child element.

Element is something that holds the position in the UI tree/ hierarchy. It manages the life cycle and the parent-child relationship between itself and the other elements. 

Render Object, on the other hand, knows about the layout and the UI.

Let us take an example where you have a central widget and text element as a child widget.

The Flutter displays “Hello World” and once you press the button, the text shall change from “Hello World” to  “Hello Youtube”. 

Now how does Flutter manage this UI change?

To begin with, let’s consider the left-hand side command. Flutter asks the center widget to create a respective element, which in this case is a single child render object element. This element holds the position in the UI when the Flutter framework uses the mounting method to mount the element to the hierarchy and gives a particular slot in the hierarchy. Thus, when Flutter asks the element to create a render object based on the configuration of the widget, which in this case is the center widget, it only cares about the position of the child widget. So, the center element here can be considered as a root element. 

The deployer looks at the text widget and asks it to create the Render object, but this time it creates a leaf render object as it is the leaf node. Flutter checks the rendered object and understands it is a leaf node, and it attaches itself to the previous element. Now the framework asks this leaf node element to create a new Render object, and this is how widget trees are painted in the screen. 

When the user presses the button, the state changes, and now the UI has to draw itself again and create a new hierarchy and position. It compares itself with the previous center widget using the canupdate function and checks for the same runtime element and matches with it. Since the text messages are different, it swaps the element with “Hello YouTube” which is then added to the root, that is, the new center widget. It then creates a new Render object and displays the new widget “Hello YouTube” on screen. Thus, to drive efficiencies, Flutter only uses the existing components and updates only the required element without wasting any time.

Creating text using Flutter Application

Go to the flutter app and edit lib/main.dart, type the following code to type” Hello World”.

import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

Hello world app on Android

Observations

  • 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. It is a good idea to have a uses-material-design: true entry in the Flutter section of your pubspec.yaml file. This will allow you to use more features of Material, such as their set of predefined Icons.
  • The main() method uses arrow (=>) notation. Use arrow notation for one-line functions or methods.
  • The app extends StatelessWidget, which makes the app itself a widget. In Flutter, almost everything is a widget, including alignment, padding, and layout.
  • The Scaffold widget, from the Material library, provides a default app bar, and a body property that holds the widget tree for the home screen. The widget subtree can be quite complex.
  • A widget’s main job is to provide a build() method that describes how to display the widget in terms of other, lower level widgets.
  • The body for this example consists of a Center widget containing a Text child widget. The Center widget aligns its widget subtree to the center of the screen.

Creating Charts using Flutter Application

Being a very good UI framework of the modern era, Flutter gives a large number of options to work with charts and graphs elegantly. The framework (more precisely pub.dev) contains a package named charts_flutter, which gives a very vast and elegant toolkit for working with charts and graphs. This package gives us a lot of options for drawing different types of plots and charts

First of all, we will add the charts_flutter dependency in our pubspec.yaml file

1. Building Bar-chart

Step 1: Preparing data — Before plotting the bar-chart, we will first prepare the data. For that, we are going to define a class PopulationData as we are plotting the population data of U.S. in the last few years.

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

class PopulationData {
  int year;
  int population;
  charts.Color barColor;
  PopulationData({
    @required this.year, 
    @required this.population,
    @required this.barColor
  });
}

Now, after defining the class, we will be defining some dummy data inside a list which we are going to plot in the bar-chart.

final List<PopulationData> data = [
    PopulationData(
      year: 1880,
      population: 50189209,
      barColor: charts.ColorUtil.fromDartColor(Colors.lightBlue)
    ),
    PopulationData(
      year: 1890,
      population: 62979766,
      barColor: charts.ColorUtil.fromDartColor(Colors.lightBlue)
    ),
    PopulationData(
      year: 1900,
      population: 76212168,
      barColor: charts.ColorUtil.fromDartColor(Colors.lightBlue)
    ),
    PopulationData(
      year: 1910,
      population: 92228496,
      barColor: charts.ColorUtil.fromDartColor(Colors.lightBlue)
    ),
    PopulationData(
      year: 1920,
      population: 106021537,
      barColor: charts.ColorUtil.fromDartColor(Colors.blue)
    ),
    PopulationData(
      year: 1930,
      population: 123202624,
      barColor: charts.ColorUtil.fromDartColor(Colors.blue)
    ),
    PopulationData(
      year: 1940,
      population: 132164569,
      barColor: charts.ColorUtil.fromDartColor(Colors.blue)
    ),
    PopulationData(
      year: 1950,
      population: 151325798,
      barColor: charts.ColorUtil.fromDartColor(Colors.blue)
    ),
    PopulationData(
      year: 1960,
      population: 179323175,
      barColor: charts.ColorUtil.fromDartColor(Colors.blue)
    ),
    PopulationData(
      year: 1970,
      population: 203302031,
      barColor: charts.ColorUtil.fromDartColor(Colors.purple)
    ),
    PopulationData(
      year: 1980,
      population: 226542199,
      barColor: charts.ColorUtil.fromDartColor(Colors.purple)
    ),
    PopulationData(
      year: 1990,
      population: 248709873,
      barColor: charts.ColorUtil.fromDartColor(Colors.purple)
    ),
    PopulationData(
      year: 2000,
      population: 281421906,
      barColor: charts.ColorUtil.fromDartColor(Colors.purple)
    ),
    PopulationData(
      year: 2010,
      population: 307745538,
      barColor: charts.ColorUtil.fromDartColor(Colors.black)
    ),
    PopulationData(
      year: 2017,
      population: 323148586,
      barColor: charts.ColorUtil.fromDartColor(Colors.black)
    ),
    
  ];

Step 2: Defining the UI — After preparing the data to plot, we will be working on the UI of plot.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Bar Chart Example'), centerTitle: true,),
      body: Center(
      child: Container(
          height: 400,
          padding: EdgeInsets.all(20),
          child: Card(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                children: <Widget>[
                  Text(
                    "Population of U.S. over the years",
                    style: TextStyle(
                      fontWeight: FontWeight.bold
                    ),
                  ),
                  SizedBox(height: 20,),
                  Expanded(
                    child: charts.BarChart(
                      _getSeriesData(), 
                      animate: true,
                      domainAxis: charts.OrdinalAxisSpec(
                        renderSpec: charts.SmallTickRendererSpec(labelRotation: 60)
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

In the above piece of code, we are using the BarChart() widget to plot the bar-chart, which gives us a lot of options to edit the graph. In our example, we have rotated the x-labels as they are overlapping each other. Other options and modifications can also be done in the chart using the properties of this widget. Also there’s a function _getSeriesData() which is defined below:

_getSeriesData() {
    List<charts.Series<PopulationData, String>> series = [
      charts.Series(
        id: "Population",
        data: data,
        domainFn: (PopulationData series, _) => series.year.toString(),
        measureFn: (PopulationData series, _) => series.population,
        colorFn: (PopulationData series, _) => series.barColor
      )
    ];
    return series;
}

Output of above coding

Image for post

Conclusion

Flutter may appear to be a fantastic cross-platform tech for Android and iOS. It has a rich experience, it is simple and easy, saves cost and is highly productive. However, it is a new language and framework to learn.

Dart is more of a mundane language, though great at its job, not much to ramble. Some might find it boring, but that probably works in its favour as it is comprehensible and easy to apply. Learning Dart is fairly easy, and anyone experienced in any C style language can pick it up quickly. It is more like having a new language to support new cross-platform technology. Flutter is a novel way to write cross-platform apps and is unencumbered by earlier technologies. It allows us to write apps to target both the platforms with ease. It is a new programming language and paradigm (unidirectional data) users have to learn and follow.

So in a nutshell, Flutter is like asking to a painter who has a new set of brushes, canvas and a paint type, never used before. The challenge is to explore this new form of art and learn to deploy these new tools. Join Great Learning’s Courses on Artificial Intelligence, and Data Science to upskill.

3

LEAVE A REPLY

Please enter your comment!
Please enter your name here

fourteen − eleven =