Building the Flutter E-Commerce app with static data

You can easily learn how to setup Flutter on your system by following the docs on their website, flutter.io.

The app contains 5 broad sections as highlighted in the bottom navigation bar of the home screen:

Home

Categories

Profile

Notifications

Bag

I’ll be walking you through the products list and detail pages and also explain how we achieved building the same. We’ll go through these in three parts:

ProductsListPage & ProductDetailPage with static data

& with data ProductsListPage & ProductDetailPage with remote data

& with data Using ScopedModel for State Management

Our end result would look like this:

We’ll start by building the UI with static data for our ProductsListPage and ProductDetailPage . You can setup your main.dart file as follows:

We have a simple MaterialApp that uses the ProductsListPage widget for its home parameter and fetches the list of routes from the routes.dart file and uses it to declare all the routes used by this app for navigation.

This is what the ProductsListPage would look like:

Starting from the top of this UI, we need to have an AppBar and that requires a parent Scaffold widget:

AppBar

Next, the _buildProductsListPage() is a method that contains a Container for the SORT and REFINE buttons. Below that is a static list of products. Hence we opt for a ListView.builder here and return the Container if the index is 0 , else we return a row for our products in the list. We are using a ListView.builder widget but we could’ve also used GridView.count widget here instead.

The SizedBox returned at index 4 is just to add some empty space after our list. You can also use a Padding widget on your ListView instead.

The code for the ProductsListPage can be found here.

Each item in this list is represented by a custom ProductsListItem widget.

We use a const constructor for this widget that contains the details that would go in this widget:

Our list item is represented as a Row containing 2 products. Hence, in the build() method for this widget, we just call our _buildProductItemCard() method twice:

The key thing to note here is that we want each product in the list to be tappable so that we can navigate to its details page when tapped. This can easily be achieved by wrapping your product widget in an InkWell widget that allows you to use its onTap() method:

Hence, you can tap on a product and navigate to the product’s detail page using the pushNamed route method from the NavigatorState i.e. Navigator.of(context) class.

The code for the ProductsListItem can be found here.

Next, this is what the ProductDetailPage would look like:

ProductDetailPage needs to be a StatefulWidget because we’re using a TabBarView with its TabController in our layout for the product images carousel and the DETAILS and MATERIAL & CARE tabs below that. Using a TabBarView requires your class to use the TickerProviderStateMixin which in itself requires a State .

I highly recommend you to read this blog that highlights the difference between extending a class and using a Mixin .

We have a leading IconButton which would help us perform the back button navigation from our details page.

which would help us perform the back button navigation from our details page. We use the bottomNavigationBar widget for our SAVE and ADD TO CARD buttons at the bottom of the page

widget for our SAVE and ADD TO CARD buttons at the bottom of the page The Scaffold 's body contains a method that defines the layout for the rest of the page as show below.

The product’s details are simply wrapped inside a Card widget with a certain elevation that contains a Column of widgets. To make the content scrollable, we wrap it inside a ListView widget.

Most of the widgets on this page are pretty straightforward, hence we’ll only be focussing on the image carousel, `DETAILS` plus `MATERIAL & CARE` tabs and the BottomNavigationBar .

Image carousel:

The DefaultTabController wraps a Stack of the images’ TabBarView and a Container that contains the TabPageSelector . Both of them use the same controller . Therefore, when one of them changes, so does the other one. Also note that the FractionalOffset for the Container is responsible for the positioning of the TabPageSelector. You can read more about FractionalOffset here.

DETAILS plus MATERIAL & CARE tabs:

Here, we’re doing something quite similar to what we did with the image carousel. We have a TabBar that displays the Tab headers and automatically handles displaying the current tab using an indicator (blue in our case).

Then we have a TabBarView that contains 2 Text widgets, one for each of our tabs.

Finally, to hook up our TabBar with the TabBarView , we just use the same controller for both of them.

BottomNavigationBar:

Our BottomNavigationBar contains 2 buttons that are aligned in a Row such that the Save button occupies 1/3rd of the space and the ADD TO BAG button occupies the 2/3rd space. We can easily achieve this by wrapping their respective widgets in a Flexible widget and providing a value for the flex parameter.

Also note the widgets for both of these is a RaisedButton so that we can make use of its onPressed() method to handle the corresponding actions.

The entire code for Part 1 can be found here. The complete source code for this tutorial can be found here.

You can follow GeekyAnts to be notified as soon as Part 2 is out!