Category: Blog, Flutter, Development

Creating a Home Screen | How to Develop an App with Flutter – Part 3

Learn how to build your first app with Flutter. This time we will focus on creating home screen.

How to build a Flutter app tutorial

Want to build an app with Flutter? Follow our series “Flutter app development tutorial for beginners”. We’ve published the following posts so far:

  1. Introduction to your first Flutter app development 
  2. Flutter Project Setup
  3. Creating a Home Screen – you are reading this
  4. Styling the Home Screen
  5. Networking and connecting to API
  6. Refining Widgets’ Layer with Provider
  7. Internationalizing and Localizing your Flutter App

What’s more, we’ve also prepared a Roadmap that can be useful in your Flutter development journey:

Whether you want to work at Flutter development company or be a freelancer, this knowledge will help you to become a Flutter developer.

Creating a home screen in the Smoge app with Flutter – introduction

In the last post about project setup with Flutter, Karol showed us how to set the Flutter environment up, so without any additional work, we can dive into the best part – coding 🙂

In this article, we will learn, step by step, how to create a home screen of the Smoge app with Flutter. In particular, we will focus on:

  • organizing your project with smaller classes and directories
  • building UI using basic Flutter widgets
  • creating a custom widget and animations
  • using assets in Flutter
  • writing the code that will be easily maintainable.

This is a preview of what we want to achieve:

How to create home screen in your first Flutter app

Download the initial code, that will be used as a basis for this part here.
The final implementation of the first screen is available here.

Skip to a section:

There are many successful apps made with Flutter on the market. Maybe your will be the next one! So, let’s get to work.

Splitting the code up

In the lib folder, we can find the main.dart file. This file is created automatically together with the entire project. Inside this file, we find three main parts:

  • main() function which is the entry point for the app. This function calls runApp() to start the framework.
  • MyApp class, which is the root of the whole app. Here we can define a home screen and a theme for the whole app. MyApp extends StatelessWidget which makes the whole app itself also a widget.
  • MyHomePage class, which is a home screen of the app. It extends StatefulWidget. That means the home screen has its State object (_MyHomePageState that starts its definition at line 46). This widget could look differently depending on its internal objects(in this case it’s counter parameter).

As you can see, all of these parts are in just one file. Let’s start with a small refactoring and move all these parts to separate files and remove default comments.

Create two directories in the lib folder:

  • app – to store classes related to app configuration: colors, icons themes, etc.
  • ui – to store screen classes

Building Smoge app step 2

Create smoge_app.dart in the app directory. Move MyApp class to the newly created file and rename it to SmogeApp.

Keep in mind that the file naming convention in Dart is using only lowercase letters and underscores for word separation. More about Dart language style you can read at Dart’s guide website.

Move MyHomePage class to lib/ui/home directory and rename the class to HomePage. Also, remove code related to the counter as we will not use it.

In main.dart leave only the main method that runs SmogeApp. After that, the code is more separated, easier to read, and maintain.

One more thing we need to change to make the project compile is to rename MyApp to SmogeApp in widget_test.dart.

Now we can run the app and see only a navigation bar and a white background.

How to build an app with Flutter – Flutter Demo Home Page

Now, let’s go to the next important element useful when you want to create your first app with Flutter and learn how to build a Flutter app – Building UI.

Building city title widget

As a top widget of our home screen, we will use SafeArea.

SafeArea widget adds padding depending on the operating system to avoid overlapping with a status bar or a notch on some phones.

The whole content is aligned vertically one after another so as a child of SafeArea we will use Column widget.

At the top of the screen, we have a label with a city name. To build it we will use Text widget.

And that is enough for now. Let’s put that in code and change _HomePageState like this:

Building of the title is located in a separate method to make code cleaner and easier to read.
Underscore (_) as a function’s prefix is used in Dart to mark this function private.

And now run the app.

How to build an app with Flutter step 3

The text label is below the status bar and notch due to the SafeArea widget.

But the text label is not centered horizontally on the screen. Why?

The problem is that the Column widget adjusts its width to cover all the content, so in our case Column width is the same as a text label.

To stretch column full screen add property crossAxisAlignment and set it to CrossAxisAlignment.stretch.

Simulator Screen Shot iPhone 11 Pro 2020 03 29 at 17.57.58

Now It looks better. Text size and font of the text label is not the same as on designs but we will fix that later 🙂

In the next paragraph, I describe another crucial element useful if you want to learn how to build an app with Flutter. Creating animations.

Creating animated widget

The next step is to create a text with a percentage at the center. This text needs to be animated from the value of zero to the given number.

Animations, Yay!

We are going to create this widget in a separate class and we will pass two values to it: fromValue and toValue. All animation logic will be inside this widget so our home page will stay clean and readable.

First, in the home directory create a new one called widgets. Here we will create all custom widgets needed on the home page. Create new Dart file animated_percentage_widget.dart and paste below code:

AnimatedPercentageWidget extends StatefulWidget because its state will be changed during the animation.
In the constructor, we can pass three parameters: fromValue, toValue, and duration. We set a default value for the duration parameter so it can be omitted during widget creation. Before calling the super method we check if all required values aren’t nulls to avoid null pointer exceptions and application crash. Also, we check if fromValue is less than toValue.

The default value of the duration parameter is created with the const keyword.
const is an optimization. It helps Flutter to easily compare representations of widgets and decide if it needs to be rebuilt.
To use the const keyword all widget’s parameters have to be final.
The more detailed explanation you can find in this post.

createState() method needs to be overridden for a stateful widget in order to create data that will drive the widget.

_AnimatedPercentageWidgetState is a private class that extends State, a generic abstract class. It is a Flutter template for creating custom widgets.

To run animation in Flutter we need instances of two classes: Animation and AnimationController

In our animation, we will use a ticker controller and a setState method.
A Ticker is an object that calls a function every frame.
Widget state includes SingleTickerProviderStateMixin. This mixin takes care of the hassle of managing the ticker. With that mixin, our state becomes secretly a ticker provider. What this means, is that the Flutter framework can ask it for a ticker.
Most importantly, AnimationController can ask it for a ticker.
AnimationController needs a ticker for its two functions. If you use SingleTickerProviderStateMixin or its cousin TickerProviderStateMixin you can give ‘this’ to the AnimationController.
AnimationController is what you normally use to play, pause, reverse, and stop animations.
Instead of pure tick events, it tells us at which point of the animation we are at any time.

In our case we want to animate from one value to another, so we will use Tween animation.
In the Tween constructor we put fromValue as begin and toValue as end parameters.
Right after the constructor, we call animate function passing AnimationController as its parameter. This function returns Animation which is driven by a passed controller.

On the animation object, we call addListener function to be notified every time the value of the animation changes.

The standard way of setting a listener would create animation and then set the listener on the animation object like this:

Thanks to Dart’s cascade notation we can call the subsequent ‘addListener method on the Animation object. ‘addListener is a void method so it does not return any value but as a cascade notation ignores any subsequent return value we still get Animation object and can assign it to _animation parameter:

Inside the listener we call the setState method. setState notifies the framework that the internal state of the object has changed. In our case, we change the _number parameter value to one provided by animation.

The last step is to call the forward method on the controller to start running animation.
Don’t forget to dispose of AnimationController. This can be done in the dispose method of the widget’s state.

As the animation is ready, what’s left is to build a Text widget with _number value:

Placing an animated widget on the home screen

Now is the time to add just created widget to the home screen. Let’s do the same for building this widget as it was for the title which is in a separate method.
Both with percentage value let’s add a label that is underneath.

How to build an app with Flutter step 5

Both widgets are one after another vertically so wrap them in Column:

Running the app we get such results:

Flutter Smoge app -step 6

The animation is working!

The whole content should be placed in the center. To achieve that we need to wrap the created column in Expanded widget, so it will take free space of parent Column and also to center content vertically inside it we will set mainAxisAlignment to MainAxisAlignment.center.

 

And now the content is in the center!

How to build an app with Flutter step 7

Creating custom widget

What we are missing on the home screen is a bottom widget with the activities.
This one will also be created as a separate widget to keep code well organized.

How to build an app with Flutter step 8

We will need some icons to build this widget so let’s start with that.
In the assets folder at the root of the project, you can find all the needed assets.

Flutter uses the pubspec.yaml file to identify assets used in the project.
Open this file and in the flutter section and assets subsection, we have to define all assets that the project uses.
To add images folder to be used by the app make such entry in the pubspec file:

Keep in mind that in case of adding files from subdirectories, we need to create an entry for each directory.

Having assets included in the project, let’s dive into widget building.

Inside the activities widget, there are three separate activities places horizontally.
Every activity looks similar, so it is a good idea to make a separate widget from it.

Building a single activity widget

So start with creating ActivityWidget:

There will be three types of activities: walking, running, and biking.
And we want to display a mark if air quality is good or bad for a given activity.
Create enums with all those types:

To ActivityWidget we will pass activity type and quality. Depending on those two values, the widget can be configured appropriately.

Let’s go step by step through this file.

  1. At the top, there is a private abstract class in which constant values are defined.
  2. Next, there are two enums described before. Enums were moved to this file in a matter of readability.
  3. ActivityWidget extends StatelessWidget as it won’t change during the widget lifecycle.
  4. The constructor receives two parameters: ActivityType and ActivityQuality.
  5. At the bottom of the file, there are three helper methods. One _titleForActivityType returns activity name based on passed activityType and the second one _imageForActivityType do the same but instead of name it returns an icon for activity.
    The last one _buildWarningBadge returns a proper widget depending on passed ActivityQuality: an empty container for good quality and an Image widget with a warning icon for bad quality.
  6. Thebuild method creates the whole widget using helper methods. Because the building is complex, private methods were created to make it easier to read.
    As a parent widget, we used Expanded as it has to expand in its parent.
    Next in the hierarchy, we put Stack to show badge warning icons above the rest of the content.
    Inside Stack, we placed a badge icon at the top, right corner. To do that badge icon have to be wrapped by a Positioned widget:The second child of a Stack is an activity container that has a white background with rounded corners and a column of an activity icon and name.
    The Container has padding from right and top equal to half the size of the warning badge. To achieve that we wrap the container with Padding widget:To build an activity container with rounded corners and shadow we used Container widget with box decoration:Inside the container, one thing that misses is the activity icon and name. These two are children of Column centered in a container.

Building an activities widget

As the ActivityWidget is finished it is time to create a widget showing all activities with their quality:

ActivitiesWidget accepts Map where the key is activity type and value is activity quality. Iterates through that map widget build next ActivityWidgets:

To place the elements horizontally we use Row. To make sure the spacing between elements as well as before and after the first and the last element is equal we set mainAxisAlignment to MainAxisAligement.spaceEvenly.

The activities widget is ready!

Placing an activities widget on the home page

Let’s add it home page to the bottom of the screen with bottom padding:

And run the app:

How to build an app with Flutter step 9

And it looks pretty good, doesn’t it? 🙂

Wrapping last screen element up

The last thing, that is missing on the main screen is the details label with an arrow underneath.

How to build an app with Flutter step 9

To build that we will use a well known already Column

Based on the design text has 50% opacity. To achieve that in Flutter we wrap Text in the Opacity widget.

How to build an app with Flutter step 10

Running the app we can see that the percentage widget takes the whole free space and the details are placed just above activities with height adjusted to its content.

What we want to achieve is to have the percentage at the center between the top label and bottom activities and details at the center between the percentage and activities.

To do that we will create Column with three children:

  • Expandable container to fill top free space
  • Air pollution information with height fitting its content
  • Details column wrapped with Expanded to fill space below the air pollution information

To place the percentage at the center, the Expanded widget above and below it has to have the same flex value.

flex determines the amount of space the child can occupy in the main axis by dividing the free space according to the flex factors of the flexible children.

The default value of flex is 1. It means that both Expanded widgets above and below percentage will occupy the same amount of space and with that, the percentage widget will be at the center.

It should look like this:

How to build an app with Flutter step 11

And the code looks like this:

The air pollution column is not wrapped in Expanded anymore so it shrinks to content size.
The details column is wrapped in Expanded to increase its size to available free space.

And the home screen looks as we desired.

How to build an app with Flutter step 12

And that’s it for now!

Congratulations, you have built your first UI in Flutter 🙂

In the next post, we will style the app by adding colors and text styles.
We will also learn how to add the smoke effect in the background.

Creating a home screen in Smoge app with Flutter – summary

We’ve learned how to create a beautiful home screen in your first Flutter app. We discussed elements like organizing your project with smaller classes and directories, building basic UI with Flutter widgets, and using assets.

How to create home screen in your first Flutter app

I hope our Flutter tutorial for beginners will help you in getting started with your Flutter mobile app development. Read the next article about styling the app with Flutter, by adding colors and text styles.

In the meantime, you can check out in10 – RSVP & ETA Tracking App which we made with Flutter.

About the author

Damian Włodarczyk

Damian Włodarczyk

iOS & Flutter Developer

iOS developer for 7 years and Flutter developer for 4 years. Damian’s interest in programming started as a hobby and then flourished into a professional career. He is passionate about his work because being a dev allows him to constantly improve.