Chapter 4
Chapter 4
Creating a Starter
Project Template
WHAT YOU WILL LEARN IN THIS CHAPTER
In this chapter, you will learn how to create a Flutter starter project and how to structure the
widgets. (I’ll cover widgets in depth in the next three chapters.) In future chapters, every time
you start a new example, I’ll refer to this chapter, which contains the steps to create a new
starter project. Like when building a home, the foundation is the most critical factor, and the
same is true when creating new apps.
It’s time to create the folder structure to keep you organized. This structure is my personal prefer-
ence, and depending on the project complexity, you might require more or fewer folders. At the
very least, for every new project, create the pages folder. It contains all the new pages created for
the app, keeping them separate for maintainability.
2. Click the Terminal button at the bottom of the Android Studio window.
Creating and Organizing Folders and Files ❘ 67
3. To create the folder structures, execute the mkdir -p folder/subfolder command. This mkdir
command creates a folder, and the -p parameter creates a folder and subfolder in one run. The last
parameter you pass is the folder/subfolder structure.
4. Run each mkdir command in the Terminal window to create each folder structure. For example,
run the mkdir -p assets/images command to create the assets/images folders. Repeat the
mkdir command for each folder structure listed here. For your convenience, I’ve listed the com-
mands for both Mac and Windows.
// From Terminal enter below commands
Mac:starter_exercise marco$ mkdir -p assets/images
Mac:starter_exercise marco$ mkdir -p lib/pages
Mac:starter_exercise marco$ mkdir -p lib/models
Mac:starter_exercise marco$ mkdir -p lib/utils
Mac:starter_exercise marco$ mkdir -p lib/widgets
Mac:starter_exercise marco$ mkdir -p lib/services
Take a look at the new folder structures. Not every project will use all of them, but it’s a great way to
stay organized. The assets and lib folders are located at the root folder of the project. The assets
folder contains items such as images, data files, and fonts, and the lib folder contains all the source code
logic, including the UI.
68 ❘ CHAPTER 4 Creating a Starter Project Template
➤➤ assets/images: The assets folder holds subfolders such as images, fonts, and configuration files.
➤➤ lib/pages: The pages folder holds user interface (UI) files such as logins, lists of items, charts,
and settings.
➤➤ lib/models: The models folder holds classes for your data such as customer information and
inventory items.
➤➤ lib/utils: The utils folder holds helper classes such as date calculations and data conversion.
➤➤ lib/widgets: The widgets folder holds different Dart files separating widgets to reuse
through the app.
➤➤ lib/services: The services folder holds classes that help to retrieve data from services over the
Internet. A great example is when using Google Cloud Firestore, Cloud Storage, Realtime Data-
base, Authentication, or Cloud Functions. You can retrieve data from social media accounts, data-
base servers, and so on. In Chapters 14, 15, and 16, you will learn how to use state management to
authenticate users, retrieve and sync database records from the cloud by using Cloud Firestore.
How It Works
Using either the Mac Terminal or the Windows command prompt, run the mkdir command with the
folder name parameter. The mkdir command creates the folder structure at the location specified.
Structuring Widgets ❘ 69
STRUCTURING WIDGETS
Before you start developing an app, it’s important to create your structure; like when building a
house, the foundation is created first. (In Chapter 5, “Understanding the Widget Tree,” you’ll explore
widgets in more detail.) Structuring widgets in an organized manner improves the code’s readability
and maintainability. When creating a new Flutter project, the software development kit (SDK) does
not automatically create the separate home.dart file, which contains the main presentation page
when the app starts. Therefore, to have code separation, you must manually create the pages folder
and the home.dart file inside it. The main.dart file contains the main() function that starts the app
and calls the Home widget in the home.dart file.
➤➤ A class that extends a StatelessWidget widget and returns the app as a widget (like I said before,
just about everything is a widget)
Note for the import package that you’ll be using Google’s Material Design. All the examples in the book
import and use Material Design. In Chapter 2, you learned that Material Design is a system of best-prac-
tice guidelines for user interface design. The Material Design components in a Flutter project are visual,
behavioral, and motion widgets. Cupertino can also be used to adhere to Apple’s iOS design language
that supports iOS-style widgets. You can use both standards in different parts of your app. Right off the
bat, Flutter is smart enough to show the native actions in both operating systems without you having to
worry about it.
For example, by importing the cupertino.dart library, you can mix some of the Cupertino widgets
with Material Design. The date and time picker work differently in Android and iOS, and you can specify
in the code which widget to show depending on the operating system. However, you’ll need to choose up
front either Material Design or Cupertino for the entire look and feel of the app. Why? Well, the base of
your app needs to be either a MaterialApp widget or a CupertinoApp widget because this determines
the availability of widgets. In step 3 of this exercise, you’ll learn how to use the MaterialApp widget.
Let’s start by adding the code to the main.dart file and saving it.
1. Import the package/file. The default import is the material.dart library to allow the use of
Material Design. (To use the Cupertino iOS-style widgets, you import the cupertino.dart library
instead of material.dart. For the apps in this book, I’ll use Material Design.) Then import the
home.dart page located in the pages folder.
import 'package:flutter/material.dart';
import 'package:ch4_starter_exercise/pages/home.dart';
70 ❘ CHAPTER 4 Creating a Starter Project Template
2. After the two import statements, leave a blank line and enter the main() function listed next. The
main() function is the entry point to the app and calls the MyApp class.
void main() => runApp(MyApp());
Android Studio shows a red squiggly line under the import statement pages/home.dart as well as
the Home() method, which has this error: The method "Home" isn't defined for the class
'MyApp'. By hovering your mouse over pages/home.dart and Home(), you can read each error.
Structuring Widgets ❘ 71
This is normal since you have not created the home.dart file containing the home page. This name
can be anything you like, but it’s always good to have a descriptive name for each page.
4. Create a new Dart file in the pages folder. Right-click the pages folder, select New ⇨ Dart File,
enter home.dart, and click the OK button to save.
5. Like in step 1, import the material.dart package/file. As a reminder, I’ll be using Material Design
for all the example apps.
import 'package:flutter/material.dart';
6. Start typing st and—wow—the autocompletion help opens. As you type the abbreviation for a
StatefulWidget class, the Android Studio Live Templates automatically fills in the Flutter widget’s
basic structure. Select the stful abbreviation.
7. Now all you need to do is to give the StatefulWidget class its name: Home. Since it’s a class, the
naming convention is to start the word with an uppercase letter.
// home.dart
import 'package:flutter/material.dart';
You’re using StatefulWidget for the Home class because in a real-world application most likely
a state would be kept for data. An example of when you would need a state is a PopupMenuItem
72 ❘ CHAPTER 4 Creating a Starter Project Template
widget on the AppBar widget showing a selected date used by multiple pages. If the Home class does
not need to keep state, then use StatelessWidget.
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}
8. Replace the Container() widget with a Scaffold widget. The Scaffold widget implements the
basic Material Design visual layout, allowing the simple addition of AppBar, BottomAppBar,
FloatingActionButton, Drawer, SnackBar, BottomSheet, and more. (If this were a
CupertinoApp, you could use either CupertinoPageScaffold or CupertinoTabScaffold.)
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Container(),
);
}
}
The following is the full source code for both the main.dart and home.dart files:
// main.dart
import 'package:flutter/material.dart';
import 'package:ch4_starter_exercise/pages/home.dart';
// home.dart
import 'package:flutter/material.dart';
Go ahead and run the project and see how your app is looking.
Notice that I added the following to Scaffold and AppBar: Container (this can be a TabController,
PageController, and so on) and FloatingActionButton.
74 ❘ CHAPTER 4 Creating a Starter Project Template
How It Works
To keep your code readable and maintainable, you structure appropriate widgets in their own classes and
Dart files. You structure your starting projects with the main.dart file containing the main() function
that starts the app. The main() function calls the Home widget in the home.dart file. The Home widget
is the main presentation page shown when the app starts. For example, the Home widget might contain a
TabBar or BottomNavigationBar widget.
SUMMARY
In this chapter, you learned how to create the starter project you’ll use for all future apps in this book.
You created folders with the mkdir command and named them accordingly to group the logic. You
also created two Dart files: main.dart for the main() function that starts the app and home.dart to
contain the code for the Home widget.
In the next chapter, we analyze the widget tree. Flutter works by nesting widgets together, and we find
out quickly that readability and maintainability takes a hit quickly. We take a look at an example of
how to flatten the widget tree.
Summary ❘ 75
main.dart The main() function starts the app and returns either a MaterialApp (Android)
or CupertinoApp (iOS).
home.dart This contains widgets that show the first page’s layout, or home page.