Building a Product Page in Flutter — Part 1

Mayowa Olunuga
6 min readMar 23, 2019

One of the best parts of Flutter is that it allows you to create beautiful and expressive native UI fast on IOS and Android. I would be showing you how to create one such UI.

We would be creating a semi-functional product page with Flutter based on a design made by Geovani Almeida. Due to the length of the content, I have divided the tutorial into two parts. This first part would cover the basic set up and layout of some of the widgets and part two would complete the project with functionality and interactions.

I would be using Android studio during the course of this tutorial, but you can use any IDE of your choice. Actions/instructions would be based on Android studio, for other IDEs please check how to perform the same action, you might have to run commands to perform them. This tutorial assumes the following,

With the above out of the way, let's get our hands dirty. 💻

Create a new Flutter Project.

From Android studio, create a new Flutter project by going to File>New>New Flutter Project. Select Flutter application on the next screen, and give your project a name of your choice in the subsequent screen. In the screen that would follow, leave the default prefilled Company domain, or add one if you have, it doesn't really matter at this moment (If you are building a product that would be deployed, then it does.).

If you have successfully completed the above, you should have a default flutter code template. Open the main.dart file and inspect the code. Run the project to see what it looks like .. cool right 😀.

Clean up the generated Code template for our new one.

Edit the _MyHomePageState class inside main.dart, remove the unused function and variable.

int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

Delete all the contents of the body widget and replace it with a simple Text widget. Also, remove the app bar widget, we would not be needing it.

appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),

Your cleaned up main.dart file should look like this now.

Visualize your Design.

Before you go ahead to start implementing UIs in Flutter, it is adviced that you visualize your UI and mentally map them into small chunks of components which would make up the larger whole. Let's visualize what we want to build.

We can see that it is mostly composed of small components that are arranged to form the whole UI. Simple! isn't it?

Creating the widgets.

Now that we have broken down our UI into small chunks, let's start building the widgets.

Replace the Center widget that you created with a SafeArea widget, and add a Column widget as the child of the SafeArea widget. This is where all our widget would live in. A column widget accepts lists of widgets and displays them in a vertical array.

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[

],
),
)
);
}

Next, we would create a function that returns a container widget and name it appBar. Our appBar widget would contain two images and a block of text that would be laid out in a row. The row would be the child of the container widget.

Let's add the newly created appBar widget to our main SafeArea widget.

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
appBar()
],
),
)
);

when you run the project, you would see just text without the icons. We would have to add the images to our project before we can see it.

Adding Images to our project.

To add images to flutter projects, we would create a folder named images in the root of our project, and copy the images into this folder.

Next, edit the pubspec.yaml file. Under flutter to link our images up. Look out for the comment # To add assets to your application, add an assets section, like this: in pubspec.yaml and edit the text below it as shown below. Make sure the indentations are correct else you would get errors.

# To add assets to your application, add an assets section, like #this:
assets:
- images/back_button.png
- images/bag_button.png
- images/heart_icon.png
- images/shoe_blue.png
- images/shoe_green.png
- images/shoe_yellow.png
- images/shoe_pink.png
- images/checker.png
- images/heart_icon_disabled.png

after adding the image paths to the pubspec.yaml file re-build the project again, this time, you should see the appBar come to life now.

Now that we have our appBar setup and know how to use images, let go ahead and add the hero image.

We can simply add an Image widget below the appWidget and have our hero image like so.

return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
appBar(),
Image.asset("images/shoe_blue.png",)
],
),
)
)

But looking at the mock-up, we would notice that the image itself is below the app bar. To achieve this, we would create another component called hero, it would be a Stack widget that would house our hero image and appBar widget. While at it, we would also add the FloatingActionButton (FAB) since it is part of the hero.

A stack widget lays out its children on top of each other, such as a text on a background Image. To place a widget in a particular position inside the stack, it should be wrapped in a Positioned widget and set its top, bottom, left or right distance from the stack container as needed. This is similar to a relative positioning in CSS and constraints in Android and IOS.

The appBar is wrapped in a Positioned widget so that it can be positioned at the top, and the FAB is also placed in a positioned widget so that it can be positioned at the bottom right of the hero.

Replace the appBar widget inside the SaferArea widget with the hero widget we just created, since our appBar widget is now inside the hero widget.

return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
hero()
],
),
)
);

Run the project now, everything should work fine, you should also see the FAB and the hero image properly placed.

Now we can create the description block

var description =
Container(child: Text(
"A style icon gets some love from one of today's top "
"trendsetters. Pharrell Williams puts his creative spin on these "
"shoes, which have all the clean, classicdetails of the beloved Stan Smith.",
textAlign: TextAlign.justify,
style: TextStyle(height: 1.5, color: Color(0xFF6F8398)),
),
padding: EdgeInsets.all(16)
);

The code block above is another way we can create a widget. Using a variable instead of a returning a widget from a function as we have been doing before.

Add the created description widget to our parent Column.

return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
hero(),
description
],
),
)
);

That out, we would create the property Widget to house the colour picker and size of the product.

And as usual, add the newly created widget to our parent Column and run the project.

return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
hero(),
description,
Property(),
],
),
)
);

Now we can see our Product page coming to life.

In part 2 of this tutorial, we would add the bottom button and style the property section of the UI. We would also add functionality to change the hero image based on the colour selected from the colour property and also simulate Favourite when the FAB is clicked.

Link to the complete code available here

--

--