Creating Your First Flutter App | Androidmonks

Creating Your First Flutter App | Androidmonks

Flutter is the latest open source Mobile SDK created by Google. It is a cross-platform application development framework and is the Google’s answer to Cordova/PhoneGap etc. After spending time working on that, I have come to the conclusion that, it is going to pave the way for the future of Applications. From seamless development cycle to quick and faster code authoring. Flutter is providing to be a very useful way to writing a Cross-platform Application.

Given that it can both compile and run for IOS as well as Android, for that matter independent of any OS is what the team is trying to achieve. In this tutorial, we will see how to create your First Flutter Application using Android Studio.

YOU ARE YOUR BOSS
I agree to have my personal information transfered to MailChimp ( more information )
Join over 5.000 visitors who are receiving our free content and learn how to program with Android. The growth of Android is estimated to reach a whooping 83% by 2020. Hop on the train and start making money!
We hate spam. Your email address will not be sold or shared with anyone else.

In order to know how to set up the environment for Flutter, you can read about setting up the environment for Flutter App development.

Flutter’s Declarative Style

Flutter is heavily dependent on a React style or Declarative style of writing code. What this means is that, there are no more, Objects to be created and passed around, or even maintaining the state of an object. Providing actions for resuming an Application/ stopping an application etc.

All of this is removed, and the developer will only have to concentrate on what the Application is intended to do, behind the scenes work of handling the objects and transitioning UI is done by the Flutter engine.

To understand how declarative style defers from the traditional style of programming take a look at the below code samples.

Object a = findViewById(R.id.obj_a);
a.setColor(Red)
View b = new View(...)
b.add(a)

The above style is called Imperative Style, meaning all the objects are tightly coupled and are mutable. You create an object and play around only with this object.

The Declarative style, however, the view configurations (such as Flutter’s Widgets) are immutable and are only lightweight “blueprints” according to the official Doc. To change the UI, a Widget triggers a rebuild on itself and constructs a new Widget subtree. This subtree is what we see all the time. Behind the scenes, there are a lot of things that happen, the developer as such needn’t worry about it.

return View(
  text: SAMPLE,
  child: ViewD(...),
)

Like you can see from the above Declarative style of programming, there are no objects floating around. The developer merely has to construct the current UI, the transitioning of the UI or the subtree creations are taken care of by the flutter engine.

This difference in programming requires a change in the way we look at a solution to a problem. This change in mindset is necessary for any Android developer. However, the beginners with Android Development/IOS development can quickly pick up the language structure as it is very straightforward in a lot of areas. There might be a need for some knowledge of how the Android App Development is done. If you are looking to get learn few basic concepts before we start the tutorial, you can take a look at, Android UI Layout for beginners post.

Understanding Widget’s

If you have had experience or even a basic knowledge of Android Application development, you will understand Android’s Views. The flutter’s Widgets are similar to the Views & ViewLayout in Android. However, unlike Android’s Views, the Widget is immutable, meaning you cannot create an object of it or for that matter, it can be modified. You will have to work with the Widget’s state in order to create any type of UI.

For those who do not have any experience in Android, then understand that, Widget’s form the building block for creating a UI. All the components that you see in your phone are made up of multiple widgets and in combination, they become one UI. Widgets are important enough to the lifecycle of the application. Since, they are immutable, meaning they cannot be changed, the Flutter in the background takes care of creating a lightweight Widget tree, everytime the UI is changed.

Take an example of swiping right and left in your application. Every time the app is swiped right, the Widget tree is reconstructed. The Widget may be of any one of the following types,

StatelessWidget

A Stateless Widget represents a Widget with no state information. That is, the widget does not hold any information with respect to its previous state, it reconstructs it whenever it needs. StatelessWidgets are useful when the part of the user interface you are describing does not depend on anything other than the configuration information in the object.

For example, in Android, this is similar to placing an  ImageView with your logo. The logo or the properties of the ImageView are not going to change during runtime. Thus, these type of scenarios calls for a StatelessWidget.

There are a lot of other scenarios in which a StatelessWidget can be used, read along to find out more about the Widget Types.

StatefulWidget

If you want to dynamically change the UI based on data received after making an HTTP call or user interaction then you have to work with StatefulWidget and tell the Flutter framework that the widget’s State has been updated so it can update that widget.

An important thing to remember is that both the Type of widgets at the heart rebuild every frame when there is a new Widget tree that is built. The only difference is that the StatefulWidget does the extra role of holding a data across frames and restores it whenever required

Combination of Stateful and Stateless widget forms the UI part of the application. There are several scenarios to decide upon the two types of widgets, some of them are,

  1. Choose a Stateless widget when there is a need to hold a static or a View that does not react to a change. For (Eg) Logo, Title Text or an Image etc
  2. Choose a Stateful widget when the widget has to react to change/user interaction. Click on a button should change the Image/Text, then go for a Stateful Widget, since the Text will be dynamically modified on the fly.
  3. Also remember, even if the child is a Stateful Widget, the parent can still be a Stateless, if and only if the parent also doesn’t react to change

Writing code for StatelessWidget

Time to see, how we will be writing the first piece of code in Flutter. There are different components when it comes to Flutter’s style of writing code, we will take a look at creating a StatelessWidget in this section.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Android Monks',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

In the first section, we saw above, about Declarative style of coding. The syntax above follows the same. The class MyApp is going to hold the root of the tree. The StatelessWidget class is the class which we are going to override.

Inside the class, we have the method Widget build(BuildContext context) which will return the Widget object. We will be building the required Widget and return it to the Flutter engine, which then will build the required native code and project it in the Application.

As given above, the MaterialApp is the Widget which we are going to return, there is a variety of Available Widget’s that can be returned, but a basic Application requires the material App Widget. This widget holds a ToolBar and a Body. In order to fill these two attributes, the required ThemeData object is called with the Colors.blue (Meaning, the toolbar is going to be Blue).

If you are an experienced developer, you can visualize or understand what the behind the scenes action will be by the Flutter engine. A beginner, on the other hand, can understand that the above class holds the StatelessWidget, which here is going to be the parent of all the widgets that we will be creating. Since the base app structure is not going to change, the StatelessWidget option seems to be a better fit.

Writing code for StatefulWidget

Since we know what a StatefulWidget will do, we can go ahead and modify the above example code with a StatefulWidget in the home attribute which we have to give.

This will give us a clearer picture of how the Stateless and Stateful widget will act together.

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Android Monks',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default placeholder text
  String textToShow = "Android Monks Example";

  void _updateText() {
    setState(() {
      textToShow = "Text Changed";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Stateful widget"),
      ),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: 'Update Text',
        child: Icon(Icons.update),
      ),
    );
  }
}

There are a lot of components in the above code, we will try to break it down to understand the entire idea of a StatefulWidget.

  1. The root of the UI is a StatelessWidget like shown in the above section. The home attribute, however, is making a call to another class called SampleAppPage. This class extends the StatefulWidget.
  2. The first thing we do as soon as the StatefulWidget is inherited is to create a constructor for that class. This is similar to the onCreate() method in our activity, where we pass the bundle back to the superclass. In understandable terms, the class which we are inheriting has to know about the child class. Thus we create a constructor for that class and call the super method on it. This will let the StatefulWidget class (And eventually the Flutter engine) know about the component which is in need of a StatefulWidget
  3. In StatefulWidget section, we learned that the only difference between a stateless and a stateful widget is in the function call of the setState() which will restore the state information that the widget holds. In order to give that call, the createState() method has to be overridden
  4. Coming on to the use of _SampleAppPageState. This is where the main logic is going to be written. The class extends the State of the SampleAppPage (which is now a stateful widget holding various state information). 
  5. Override the build method with the required Widget type(We saw MaterialApp in the stateless widget, here it is going to be a Scaffold). There can be any number of widgets added inside this.
  6. The floatingActionButton attribute is then created with the required property. The ToolTip specifies the name on the ActionButton. The main attribute to look at is the onPressed
  7. The onPressed is making a call to the helper method that we have defined locally. All it does it, it calls the setState() method every time the button is clicked.
  8. The setState() method, in turn, changes the textToShow variable to what we require. The widget is reloaded, and the new text appears.

This is how the entire flow of the basic layout of the Flutter app works. For a beginner app developer, this will be very easy to pick up, since the flow is linear. All you need to keep in mind is that

FLUTTER IS ALL ABOUT CREATING WIDGET TREES!

Creating Layouts in Flutter

This section is another comparison to what the Android offers in terms of creating UI. The major part of Android lies in creating Layouts. Layouts play an important role in terms of arranging the elements on the screen. They act as the Root for any UI. The Flutter, however, does not work that way. Everything you see on the screen is a widget. You create multiple widgets, arrange them according to your needs and create the UI.

Hence, there is no concept of Layouts, but still, there are widgets within which there can be other widgets. Meaning, stacking one widget over another.

The Flutter equivalent of a Layout(Still the concept of Layout is totally different to that of the widgets) are Rows, Columns & Stack. You can create a LinearLayout, RelativeLayout or for that matter any complex layouts like Coordinator Layout equivalent in Flutter using Widgets.

Combination of Rows & Columns can create a lot of Various Layout like structure. The purpose of these two widgets is to give some order to the arrangement of elements on the screen. See the below implementation to know more about creating Layout equivalent in Flutter.

Create a Row Widget in Flutter

In order to create a row widget, you make use of the Row class. Return this class inside a Stateless or Stateful widget and you can get the structure made.

@override
Widget build(BuildContext context) {
  return Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text('Row One'),
      Text('Row Two'),
      Text('Row Three'),
      Text('Row Four'),
    ],
  );
}

It is important to understand when and where the Row class can be used. Creating a Row widget is particularly helpful when you want to horizontally arrange elements/widgets. Meaning, there is a TextView that needs to be stacked horizontally, it can be done by creating a Row widget inside a Stateless widget and implementing them. This type of Tree creation will eventually build the entire UI.

Create a Column Widget in Flutter

To create a Column Widget in Flutter, make use of the Column widget class. Return this class inside a stateless or stateful widget implementation and the column widget is created.

@override
Widget build(BuildContext context) {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text('Column One'),
      Text('Column Two'),
      Text('Column Three'),
      Text('Column Four'),
    ],
  );
}

Similar to the Row widget, it is important to know when to use the Column widget. Create a column widget when you have a requirement to align elements in a Vertical fashion. It is easy to get carried away with creating nested Widgets one below the other, however, make sure to always flatten the UI as much as possible. This means that, whenever there is a need to created nested Widget trees, look for other options to reduce nesting as much as possible.

Flutter being all about Trees, it is easy to get carried away with creating a huge tree. Always remember, shorter the tree, easier it is to traverse or re-construct whenever required

Row & Column Widget Parameters

The Row & Column widget additionally takes in a lot of parameters. Some of the parameters are,

MainAxisAlignment:

This is a similar property like Gravity in Android. This lets you set the widget elements in either center, start or end. See the below representation to know more.

Column widget with MainAxisAlignment as center
Column widget with MainAxisAlignment as the center
Column widget with MainAxisAlignment as start
Column widget with MainAxisAlignment as the start
Column widget with MainAxisAlignment as end
Column widget with MainAxisAlignment as the end

CrossAxisAlignment

This property lets you align the children according to the cross axis of the Widget. It means if we use Row widget the individual’s children gravity will be on the basis of the vertical line. And if we use Column widget the individual’s children gravity will be on the basis of horizontal line.

To understand better, see the below samples.

Row widget with crossAxisAlignment as start
Row widget with crossAxisAlignment as start
Row widget with crossAxisAlignment as end
Row widget with crossAxisAlignment as the end

 

Row widget with crossAxisAlignment as center
Row widget with crossAxisAlignment as the center

mainAxisSize
This property lets you perform the match_parent, wrap_content like result. Meaning, it will either wrap to the space the children take, or it will expand to the space of its parent tag. To get a clearer picture, see the samples below.

Row widget with the mainAxisSize as max
Row widget with the mainAxisSize as max
Row widget with the mainAxisSize as min
Row widget with the mainAxisSize as min

Running the App

All set and done, time to see how you can run the simple App that you created. Take the stateless widget for example and start the device emulator.

Run the main.dart using the Run option present in the top corner. This will start the application and you end up with the below App.

Final App using Flutter
App created using Flutter

The beauty with Flutter is that you can create a Hot Reload. All you need to do(If you are using Android Studio) is to save (Ctrl+S or Cmd+s) and the Application reloads!! Isn’t that cool. This is one of the many features that the Flutter engine can do.

This will definitely help with the development time and improve upon the slow Gradle builds that you will have to endure during the Native Android development.

That’s it for the First Flutter Application development. Make sure to comment your queries below.

“Learn and Be Curious”

Also Read  TimePicker in Android - Implementation and Overview

Leave a Comment

Your email address will not be published. Required fields are marked *