As an introduction to this tutorial, I’d like to tell you a little bit about the importance of Mobile Ecommerce.

62% of people who own a smartphone have made a purchase using their phone in the past six months.

82% of Internet users in the United States have used a mobile device to shop online

35% of US consumers use only their mobile device to buy online

In 2017, the US had $156 billion in mobile commerce sales

By 2021, experts estimate that US mobile commerce sales will eclipse $420 billion

Conversion rates from mobile apps are three times higher than mobile sites

Mobile shoppers spend twice as much money as other customers

53% of smartphone users buy from company-specific apps

42% of smartphone users plan to do more shopping from their mobile devices in the coming year

Source: https://buildfire.com/mobile-ecommerce-stattistics-data/

Now that we know a little be more about the business part, let’s talk about the actual code.

First, as usual, I suggest you get the source code from Cybdom Github.

Coding time: 2h56

Ecommerce App: Home Page

An important thing when you get a design from your designer is looking at it, then separating it into smaller pieces, Widgets in Flutter.

The first thing I notice is the special background color, we have two of them. So how do we achieve that in Flutter?

I choose to use a Row with 2 Flexible containers:

Row( children: <Widget>[ Flexible( child: Container(color: darkBg), flex: 3, ), Flexible(child: Container(color: lighterBg)), ], ),

With this out of the way, we have to figure a way to show all of our content on top of this background. For this purpose, we use the Stack Widget.

Wrap your background and your actual content inside a Stack and there you go. Now we can focus on the rest of the app.

Instead of using an AppBar I preferred to use a Row:

Menu

Row( children: <Widget>[ RichText( text: TextSpan( children: [ TextSpan( text: "Lamp", style: TextStyle( fontSize: 31, fontWeight: FontWeight.w200, letterSpacing: 1.3), ), TextSpan( text: "ster", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 31, letterSpacing: 1.3), ), ], ), ), Spacer(), IconButton( icon: Icon( CupertinoIcons.search, color: Colors.white, ), onPressed: () {}), IconButton( icon: Icon( FontAwesomeIcons.borderAll, color: Colors.white, ), onPressed: () {}), ], ), SizedBox( height: 15.0, ),

To achieve the text effect with the “Logo: Lampster” I used a Rich Text this is a powerful widget that we can compare to a Span in HTML coding.

Interactive Menu

Today I tried to put my laziness aside and I created a nearly functional Menu.

class Menu extends StatefulWidget { @override _MenuState createState() => _MenuState(); } class _MenuState extends State<Menu> { int active = 0; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List<Widget>.generate( 3, (i) { return InkWell( onTap: () { setState(() { active = i; }); }, child: Column( children: <Widget>[ Text( categories[i], style: TextStyle( color: Colors.white, fontWeight: active == i ? FontWeight.bold : FontWeight.w100, fontSize: 17.0), ), SizedBox( height: 5.0, ), active == i ? Container( width: 7, height: 7, decoration: BoxDecoration( color: accent, shape: BoxShape.circle, ), ) : Container( height: 7, width: 7, ), ], ), ); }, ), ); } }

The principle is simple we have a Row, we specified that we should equally space between each child.

The child itself is a Column with the Category Text and a dot below it. If the category is active then it’s Text is bold and we show the dot otherwise it’s normal and there is no dot.

To make the widget interactive we must use a Stateful Widget. We wrap the column inside an InkWell that has an onTap property used to set the currently active element.

Secondary menu

This is one of the simplest parts of the app, we have a Row, the first child is an IconButton, other children are expanded Containers, one of them has a LinearGradient as a decoration.

Bottom Navigation

This one looks pretty nice, and I made it into a separate widget, it’s still not interactive yet but you can just copy the code and use it on your app it looks very good in my opinion.

If you want me to make a tutorial on how to create such a Bottom App Bar and add animations and interactivity please share this article. I will do it after 50 shares.

For now, this is the code that we have:

class MyBottomNavBar extends StatelessWidget { @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Container( padding: EdgeInsets.symmetric(horizontal: 11, vertical: 7), decoration: BoxDecoration( color: Colors.white12, borderRadius: BorderRadius.circular(19), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Icon(Icons.home, color: accent), SizedBox( width: 9.0, ), Text( "Home", style: TextStyle(color: accent), ), ], ), ), Row( children: <Widget>[ Icon( Icons.shopping_cart, color: Colors.grey, ), ], ), Row( children: <Widget>[ Icon( Icons.favorite, color: Colors.grey, ), ], ), Row( children: <Widget>[ Icon( Icons.settings, color: Colors.grey, ), ], ), ], ); } }

Nothing fancy, just a Row with some Text Widgets, and the Active item is represented by a Container with rounded corners and transparent white background.

Page View Product

I left the best for the end!

In this app, our products are presented inside a PageView.builder, remember we use PageView.builder when we have a List of objects and we are not sure of how many items there are.

class MyProductContainer extends StatelessWidget { final int id; const MyProductContainer({Key key, this.id}) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { Navigator.pushNamed(context, '/details'); }, child: Container( margin: EdgeInsets.all(15.0), width: MediaQuery.of(context).size.width, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Expanded( child: Container( child: Stack( children: <Widget>[ Container( padding: EdgeInsets.all(5.0), margin: EdgeInsets.all(15.0), child: Image.network( products[id]["pictureLink"], fit: BoxFit.cover, ), decoration: BoxDecoration( color: productColors[id], borderRadius: BorderRadius.circular(15.0), ), ), Positioned( bottom: 0, right: 0, child: Container( padding: EdgeInsets.all(15.0), decoration: BoxDecoration( shape: BoxShape.circle, color: accent, boxShadow: [ BoxShadow( color: accent, offset: Offset(0, 3), blurRadius: 5.0) ], ), child: Icon( Icons.favorite, color: Colors.white, ), ), ) ], ), ), ), SizedBox( height: 5.0, ), Text( products[id]["productName"], style: TextStyle(fontSize: 19, color: Colors.grey), ), SizedBox( height: 5.0, ), Text( products[id]["price"], style: TextStyle( fontSize: 19, color: Colors.white, fontWeight: FontWeight.bold), ), ], ), ), ); } }

The first thing you do when you have a list of products is keeping track of the product ID that’s very important.

The product title and the price are just Text widgets we use the ID to get those pieces of information from our product list.

However, the interesting part is how can we put the favorite button exactly in the right spot every time?

For use again our lovely widget Stack!

We put the product Image inside a container we give it a BorderRadius and background color, but the important part is giving it a Margin for our “Favorite” button to stick right between the Container and the Stack. Now, all we have to do is put Icons.Favorite inside a container, give it some padding and a BoxShape.Circle and put all of these inside a Positioned Widget and set the bottom value to 0 and the right value to 0 and that’s it!

We have finished with part one of the app, hopefully, tomorrow we will talk about part two:

Did you like this tutorial? contribute by paying what you can through Paypal!

options Option 1 $1.00 USD Option 2 $5.99 USD Option 3 $10.00 USD

You can’t pay money? No problem just share the article it is as valuable as money to me 😊.