A Beginner’s Guide to Flutter (Part 1)

Deepak Jogi
14 min readAug 27, 2021

This will be a 3 Part Guide

Part 1 : Building the User Interface

Part 2 : Adding Functionality

Part 3 : External Packages and What Next?

This guide assumes that you already have a flutter and an Android emulator running if you do not try to get it up and running first by referring to https://flutter.dev/docs/get-started/install.

I’ll be using Android Studio but feel free to use the Editor of your choice.

Okay without further ado, let’s get right into it.

Aim of this article

We’ll be making the default flutter app (sort of like a hello world app for flutter). Every time we press the ‘+’ button the value of the counter will increase and it will display the current Value.

Part 1: Building the User Interface

What we’ll be covering in this part

  1. Creating your first Flutter Project
  2. Setting up a test device
  3. Running an Application on the test device
  4. File Structure
  5. Creating the UI of the Application
  6. Container Widget, Scaffold, Appbar, Floating Action Button
  7. Wrapping and Extracting Widgets

1. Creating your first Flutter Project

First things first fire up Android Studio (or VS Code) your first screen should look something like this.

Choose “Create New Flutter Project” option, now this should open up the following menu, Choose “Flutter Application” and press the “Next” Button.

In this new menu that opens up, give the project a Project Name. I just named it my_first_flutter_app.

Also, select the location where the project will be stored and the location where you have installed the flutter SDK (Try to avoid whitespaces in folder names). The Description hardly matters.

Okay now press the Next Button

We have to choose a Package name for our app.

Package Names usually have the structure com.company_name.app_name

For now, I’m giving the name “com.cse.myfirstflutterapp” but you can name it whatever you want but make it the same format.

Well that’s it you just created your first flutter project and the window should look something like this.

2. Setting up a test device

First, let’s open an android emulator to run our app.

Optional: You can choose to use USB debugging instead of an emulator. For this just enable USB debugging on your smartphone and connect your phone to your PC via a USB cable and allow USB debugging from the PC on your phone when prompted, you should now be able to run your apps on your phone in real-time. (I personally use USB debugging as it is more reliable)

If you chose to use an emulator over USB debugging click on the AVD (Android Virtual Device) manager button as shown below.

I am assuming you have already installed the emulator SDK, If you haven’t done this refer to this guide.

Okay now let’s create an emulator you can choose any option you want for your virtual device or just follow what I have done to create a Pixel 4 device.

Click on Create Virtual Device
Choose Pixel 4

Choose the Android version you want the device to run. For now, just go with the latest android version. But in usual cases we have to check compatibility in older versions of android as well.

You don’t really need to change anything in the above window, Click on finish. Now we can see our Android Virtual Device (Emulator) has been created. Run the emulator as shown below.

The emulator will now show up just switch it on as shown below. Note that it will take some time on the first run.

And voila we have got a virtual device to work on.

3. Running your Application

We can see that the new project that we created already has some code inside it. Let’s try to run this default code.

First, choose the device that you want to run your application on (The virtual device or the device you are debugging through USB).

Now click on this green triangle to run your default code.

The first run will take some time but you can see the code being executed in the bottom part of your editor on the run tab.

So the Default App should appear on your emulator feel free to play around with it and get used to it. Our aim is to recreate this app from scratch and add some more stuff to it.

You can stop the execution if you want by using the stop button.

Okay, now we need to talk about Hot Reload and Hot Restart.

3.1. Hot Reload and Hot Restart

Once your app is running we can use the hot reload button to reflect the changes you made into the code immediately.

Now on the emulator press the ‘+’ button a few times.

Now I’m gonna make a small change in the default code, Scroll down to the part of the default code shown below.

Change the text to ‘The number of time the button has been pressed = :’

Now if you press the hot reload button you get the following change almost instantaneously.

Now if instead of the hot reload button you had pressed the run button again we perform a Hot Restart

As you can see the number has been reset, this is the difference between hot reload and hot restart.

Hot restart destroys the preserved states of our app, and the code gets fully compiled again and starts from the default state. It takes more time as compared to hot reload but takes less time than the full restart function. (Definition taken from geeks for geeks and is linked below)

Hot reload will not change the state of the app. As we observed the number in the counter did not change.

Read more about Hot Reload and Hot Restart

4. File Structure in Flutter

We can see the file structure of our project on the left-hand side of the editor in the Project Window. Expand the folder called my_first_flutter_app (or whatever you named your project)

As we can see there are two folders called android and ios these contain files necessary for exporting our flutter app into each platform we will only be bothering with android for the time being. These contain native code in Java/Kotlin/Swift. But for now, we needn't bother with these folders.

Native code is stored here

We can also see that there is a folder called lib

This is where we write flutter code. In fact, the file with the default code we ran is main.dart. In flutter, we use dart files and code in the dart language. In a normal case, we will be working with tons of dart files but since this is our first app we will work with just “main.dart”.

Also, see that we have a file called “pubspec.yaml” this is a very important file but we will discuss what it does towards the end.

We have covered a lot of basics and now we are ready to build our very first app (maybe?).

5.Creating the User Interface from Scratch

First things first let's delete all the default code and make our main. dart file empty.

Let us start by importing a package called material.dart as shown below. This package contains a lot of useful resources like basic widgets and other important stuff.

Speaking of widgets

5.1 What are Widgets?

Basically, everything in flutter is a widget

What we do is use the existing widgets mix and mash them up and create widgets of our own.

Read more about widgets here.

Okay as we were saying let’s import the “material.dart package”. The code is given below.

import 'package:flutter/material.dart';

Now let us also add the main function as given below. the runApp(MyApp) function basically lets you run the App that you will be writing code for in a widget called MyApp();

import 'package:flutter/material.dart';void main() {
runApp(const MyApp());
}

As we can see we are getting an error saying MyApp isn't a class. This is because we haven't declared the widget MyApp() which is our app’s base widget.

So let’s start by declaring a Stateless widget.

Stateless widgets are widgets that do not change once it has been rendered on the screen. We will see what this means as we progress.

Okay, there are two ways to declare a stateless widget.

  1. Typing the code
class WidgetName extends StatelessWidget {
const WidgetName({Key? key}) : super(key: key);

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

2. Using the shortcut

Start typing the keyword “stless” in your code

Click on the prompt that says stless (New Stateless widget)

A new stateless widget will now be created we can now enter the name of the widget

Stateless Widget that has been created
We named it MyApp

So now our main.dart file code looks like

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

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

Okay as we can see the Widget called MyApp is declared as a class that extends the StatelessWidget Class and it returns a Container Widget. We will see more about containers later but we won’t now because we will be replacing it soon.

We can try running our app now.

We should get a black screen as we haven’t given any UI in the app.

Let us replace the Container() widget with a MaterialApp() widget.

When we do this our code should look like this

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Container()
);
}
}

We are declaring a MaterialApp which is usually used as the base widget in almost every app. This contains the basic presets we need.

We can hot reload this

and nothing should change we should still get a black screen.

Now let us talk about the Container widget.

5.2 Container Widget

The container widget is basically a box in which we can put stuff.

In our case, we will be putting a Text Widget inside the container and see what happens. We put other widgets inside a container by giving the widget in the child parameter as shown below. In the below case the text widget Text(“Hello World”) is passed as a child of the container.

Don’t forget the Commas

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Container(
child: Text("Hello World"),
)
);
}
}

We can do a hot reload and we should get the text in our device.

Well even though we got our text the app looks low-key weird. Let’s try to beautify this. We will be doing this by using a Scaffold Widget

5.3 Scaffold Widget

The Scaffold is a widget that gives a structure to our app containing an AppBar, a Body (body contains the text widget in our example), a Floating Action Button, App Drawer and so much more.

Let us replace our container with a Scaffold

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: Text("Hello World"),
),
)
);
}
}

The body of the scaffold is still our container with the text widget. Let us hot reload (or hot restart) and see what happens.

It instantly looks so much better but the layout looks weird and seems to be out of the screen let’s fix this.

Let us first give our app an App bar.

5.4 The App Bar

Inside the Scaffold provide an “AppBar” in the “appbar” parameter. We are using the default AppBar Widget (given as AppBar()) here but we can also use custom AppBars if we want.

return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Container(
child: Text("Hello World"),
),
)
);

Let’s try hot reloading.

We have got an app with an appbar now, try playing around with it and changing the text.

5.5 Floating Action Button

Let us now add a floating action button to give input to our counter app. Add a floating action button inside the Scaffold. The child of the button is an icon widget which gives an icon to indicate what the button does.

home: Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Container(
child: Text("Hello World"),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
),
)

But now we are getting an error (the red squiggly lines indicate errors)

If you hover your cursor above the redline you can see what the error is

The error message

The error says “The named parameter ‘onPressed’ is required”

the onPressed parameter tells the button what to do when it is pressed.

for now I’m gonna give an empty inline function that does nothing when the button is pressed, we will add functionality later.

floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{},
),

If we click on the button nothing will happen because the onPressed function is just an empty function we will add functionality later.

5.6 Wrapping widgets and the Center widget

Let us change the position of our text widget to the center of the screen

We can do this by using a center widget as a parent of the container. The code that we want is (inside body of the Scaffold Widget)

body: Center(
child: Container(
child: Text("Hello World"),
),
),

We can either type this in or we can use a shortcut to do this.

Giving a widget a parent is called wrapping a widget (Here Center widget is the parent and the Container is the child)

Wrapping a widget with a parent is easy. Right-click on the widget you want to Wrap (Container in our case)

Choose “Show Context Actions”

Choose “wrap with widget

Change widget to Center to wrap with Center Widget

Now let us try running our app with a hot reload.

And Voila our App looks so much better.

5.7. Extracting Flutter Widgets

At this point, our MyApp() widget is getting really crowded let’s avoid this by taking everything inside our MaterialApp and create a new widget called HomePage(). This is really easy to do with shortcuts. Right Click on the Scaffold Widget.

Choose Extract Flutter Widget from Refactor

Now name the new widget as HomePage and press Refactor

Now our code should look like

import 'package:flutter/material.dart';void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("Hello World"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{},
),
);
}
}

Now we have the HomePage as a separate widget and have passed the HomePage as the home of the MaterialApp automatically.

That’s it, we are done with the UI. Give yourself a pat on the back and head on over to Part 2 when you’re ready.

Head over to Part two

--

--