Section 1: Flutter “Must Know” Basic Widgets — Beginner’s guide

Joan Nabusoba
10 min readOct 26, 2022

Flutter is a great framework for developing cross-platform apps. The foundation of UI development is widgets, so let us dive in to create a simple design to understand widgets. Let us create the following simple app:

Contents

  1. Create New Flutter App
  2. Creating the AppBar Widget
  3. Adding Images in Flutter
  4. Adding body to display the content in the page
  5. Adding the Title and Subtitle section
  6. Adding Actions Section
  7. Adding the Paragraph section
  8. Adding Floating Action Button (FAB)
  9. Video Version of Tutorial

Create New Flutter App

First, create a new flutter app.

On VS Code, click on View>Command Palette.

Then, search for Flutter and select Flutter: New Project

Select Application

Select a folder where you want to keep your flutter apps. Then, give the app a name. I will call mine my_new_flutterr, but feel free to give it a name of your choice, then press enter. Let it build till all the folders are ready.

You should e able to see this

The main.dart file has initial code that when you run, it will produce a counter button that upon click it increments the text. We are not going to use it. Delete everything from where class Myhomepage begins

Delete the title and the comments so that you have the following:

import 'package:flutter/material.dart';void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}

The line home: will have an error, since we have referenced a class that doesn’t exist. To resolve this, create a new folder in the lib folder and call it screens. This is to just separate and arrange our code. Then create a new file inside the screens folder, and call it home_page.dart.

In the new file home_page.dart, type stl and select Flutter Stateless Widget from the shown list of commands. This will recreate code with class name MyWidget. Replace the text MyWidget with MyHomePage. Finally, delete the top imports, then import material.dart library by clicking on StatelessWidget text, and choosing from the options of the bulb on the left. It will look like this:

import 'package:flutter/material.dart';class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Container();
}
}

Now, go to main.dart file and import the MyHomePage class as shown:

Your main.dart should now look like so:

import 'package:flutter/material.dart';
import 'package:my_first_flutterr/screens/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}

Now, let us head to home_page.dart file to create our widgets. Replace Container(); with Scaffold(); and let us begin adding widgets. What is a Scaffold? It is like a main widget in flutter, that provides route to many widgets like drawer, AppBar, bottom navigation, floating action button and body, which carries other widgets.

Let us now create an appBar.

Creating the AppBar Widget

Inside the Scaffold(); in the brackets, press enter and type the following code:

//APPBAR
appBar: AppBar(
title: Text("Adventure"),
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.search,
color: Colors.white,
),
),
],
),

The appBar consists of a title which is a Text widget, and action property that can contain a series of widgets inside. We have added an IconButton widget with a search icon, therefore our action can be search. Run the app, you can select chrome

In case you do not see Chrome, make sure you enable web in your flutter

You should be able to see the following:

At chrome’s More tools section, select Developer tools and click on Toggle Device Bar to see minimized simulation

Since we are using images, we will need to download an image and create a folder in our project. Then, add the resource to pubspec.yaml file

Adding Images in Flutter

Create a new folder at the root of the project and call it images

Copy and paste an image from pixabay.com or unsplash.com. Make sure you have renamed it to a suitable name you will remember. Back to VS code, you will be able to see your folder with the image as shown:

Now, go to pubspec.yaml file and uncomment out the assets so that it looks as follows:

Make sure the indentation is EXACTLY as shown above, to avoid errors in the pubspec.yaml file. Save your file and click Get packages which is a download icon at the top right of the IDE

Just to be safe, stop running the application, we add images code first before you run again.

Adding body to display the content in the page

Go back to home_page.dart. After the AppBar Widget (make sure it ends with a comma), add the following code:

//MAIN CONTENT
body: Container(
child: ListView(
children: [
//IMAGE
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/forestbg.jpg"),
fit: BoxFit.cover)),
),
//SPACE
SizedBox(
height: 20,
),
],
),
),

The body section is where we add content for the main page. We have a Container() widget, with a ListView widget as child. ListView as a widget can have many widgets, so that is where we will add our widgets, inside the square brackets.

The Image

We shall use the Container widget to display our image, inside the BoxDecoration property. To make the image fit and be responsive, the width of the container is 100% by use of MediaQuery, and the height is 30% of the screen. Make sure you call the image in the AssetImage, exactly the way you have renamed your folder and the image plus the extension.

We have added a space using SizedBox widget after the Container with the image, to enable us add more content below.

Below is our code so far and our result upon running the app:

import 'package:flutter/material.dart';class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
//APPBAR
appBar: AppBar(
title: Text("Adventure"),
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.search,
color: Colors.white,
),
),
],
),
//MAIN CONTENT
body: Container(
child: ListView(
children: [
//IMAGE
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/forestbg.jpg"),
fit: BoxFit.cover)),
),
//SPACE
SizedBox(
height: 20,
),
],
),
),
);
}
}
The result of the above code so far

Adding the Title and Subtitle section

Within the square brackets of ListView widget, after the SizedBox closing bracket, press enter and type the following:

//TITLE, SUBTITLE SECTION
Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Forest Trail",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 2,
),
Text(
"Shanzu, Mombasa",
style: TextStyle(color: Colors.black54),
),
],
),
),
Icon(
Icons.star,
color: Colors.red,
size: 18,
),
Text("41"),
],
),
),
//SPACE
SizedBox(
height: 30,
),

we have added Padding widget to add spaces left and right, using the padding property. We have added spaces left and right of size 20. The Padding widget has a Row as a child. A Row widget can have multiple widgets, and arranges them horizontally.

Inside the Row, we have Expanded widget that tells the Row to take the entire space, so that any other widget added after it takes the remaining horizontal space. In the Expanded widget, we have added a Column widget which can also inherit multiple widgets. The Column has a property called crossAxisAlignment: CrossAxisAlignment.start, which tells the content of the Column to arrange items from left to right.

To understand more about crossAxisAlignment in columns and rows, bear in mind this:

  • Columns by default arranges items from top to bottom. Therefore, that is the mainAxis. The crossAxis in a column is left to right.
  • Rows by default arranges items from left to right. By default, that is the mainAxis. The crossAxis of Row is top to bottom.

Inside the Column, we added 2 Text widgets with a space using SizedBox in the middle.

After the Column, we added Icon widget, Text widget. So, this is the small hierachy:

  • Padding > Row > Expanded (Column(Text, SizexBox, Text) ), Icon, Text
  • SizedBox

The result is as follows:

Adding Actions Section

After the above code, type the following:

//ACTION SECTION
Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//FIRST CHILD
Column(
children: [
Icon(
Icons.call,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"CALL",
style: TextStyle(color: Colors.blue),
),
],
),
//SECOND CHILD
Column(
children: [
Icon(
Icons.directions,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"ROUTE",
style: TextStyle(color: Colors.blue),
),
],
),
//THIRD CHILD
Column(
children: [
Icon(
Icons.share,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"SHARE",
style: TextStyle(color: Colors.blue),
),
],
),
],
),
),
//SPACE
SizedBox(
height: 20,
),

Now that we know how Rows and Columns work, we want to arrange our action items horizontally in a Row. We then added the space to allow for more content.

The MainAxisAlignment.spacebetween in the Row allows the Row to space it’s children by adding equal spaces in between them. Here is the result of the above code:

Adding the Paragraph section

After the above code, add the following. Copyright of text: Google search

//PARAGRAPH SECTION
Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
"Bamburi Forest Trails is located along Mombasa-Malindi Highway opposite Bamburi Beach Hotel. Open daily from 8:00 am to 4:30 pm. Visitors are required to leave the park by 6:00 pm. For further information and booking, call: 07 21 381 949 or visit www.lafargeecosystems.co.ke."),
),

we started by adding padding, that has a child of Text Widget. The result:

Adding Floating Action Button (FAB)

As we discussed earlier, FAB is a widget inside the Scaffold. So, we shall add anywhere within the Scaffold.

Just above the end of the Scaffold and below the Container, e.g.

Add the FAB code

//FAB
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(
Icons.message,
color: Colors.white,
),
),

Result:

The entire Code

import 'package:flutter/material.dart';class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
//APPBAR
appBar: AppBar(
title: Text("Adventure"),
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.search,
color: Colors.white,
),
),
],
),
//MAIN CONTENT
body: Container(
child: ListView(
children: [
//IMAGE
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.3,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/forestbg.jpg"),
fit: BoxFit.cover)),
),
//SPACE
SizedBox(
height: 20,
),
//TITLE, SUBTITLE SECTION
Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Forest Trail",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 2,
),
Text(
"Shanzu, Mombasa",
style: TextStyle(color: Colors.black54),
),
],
),
),
Icon(
Icons.star,
color: Colors.red,
size: 18,
),
Text("41"),
],
),
),
//SPACE
SizedBox(
height: 30,
),
//ACTION SECTION
Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//FIRST CHILD
Column(
children: [
Icon(
Icons.call,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"CALL",
style: TextStyle(color: Colors.blue),
),
],
),
//SECOND CHILD
Column(
children: [
Icon(
Icons.directions,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"ROUTE",
style: TextStyle(color: Colors.blue),
),
],
),
//THIRD CHILD
Column(
children: [
Icon(
Icons.share,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Text(
"SHARE",
style: TextStyle(color: Colors.blue),
),
],
),
],
),
),
//SPACE
SizedBox(
height: 20,
),
//PARAGRAPH SECTION
Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
"Bamburi Forest Trails is located along Mombasa-Malindi Highway opposite Bamburi Beach Hotel. Open daily from 8:00 am to 4:30 pm. Visitors are required to leave the park by 6:00 pm. For further information and booking, call: 07 21 381 949 or visit www.lafargeecosystems.co.ke."),
),
],
),
),
//FAB
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(
Icons.message,
color: Colors.white,
),
),
);
}
}

Video Version of Tutorial

If you want the video version, you can follow here:

Let us now go to Section 2 to learn navigation in Flutter

--

--

Joan Nabusoba

UI/UX | Flutter Developer | React | I mentor young women in Mombasa to code | I learn by doing and sharing