Android Fully Functional Ecommerce App sample example Tutorial from Scratch – Part 1

By | October 15, 2015

Nowadays every buisness requires to have its own business app for mobile users. Although a business website serves the purpose of online selling of products, but for mobiles user’s even the most responsive websites can prove inconvenient for shopping online.

eCommerce Android App

ECommerce Android App Project

In this Article we will develop a complete eCommerce app for Android platform from scratch.

The main features of the app would be:

  1. Category based product list
  2. Adding/Updating products to Cart
  3. User Authentication through phone SMS using OTP Verification
  4. Multiple Address List for each user
  5. Order History for every user
  6. Order Updating & Cancelling Features
  7. Order Tracking System

Pre-Requisites:

  1. Basic programming skills in Java
  2. Basic Android Concepts

Use Cases:

  1. To bring your offline business to online at mobile platform
  2. An android app for existing online shopping website
  3. If you are a student, then a prototype for your school projects
  4. A sample example of Android App for eCommerce

We will be developing a sample app for online grocery store including fruits & vegetables:

Let’s begin the app development:

– Create a new Android Application Project and select blank activity type for the new project as shown in the screenshots below:

ecommerce Android app

ecommerce Android app

ecommerce Android app blank activity

ecommerce Android app blank activity

Now create the following few packages inside the src folder of the newly created android application project, “Ecommerce”:

  1. com.tutorialsface.fragments – For storing all the fragments required by the project
  2. com.tutorialsface.listadapters – For storing all the adapters of custom listviews that will be used in product list, cart, order list etc..
  3. com.tutorialsface.utils – For storing other utility classes like Contants, static methods etc..
  4. com.tutorialsface.models – For storing various model classes like Product, Order etc..
  5. com.tutorialsface.imageloader – For storing Image loader files which will be used for loading images of product inside listview
  6. com.tutorialsface.interfaces – For storing various custom callbacks interfaces required in the project( Sample Example of callbacks is here)
ecommerce project hierarchy ecommerce project hierarchy[/caption]

Now let’s create a layout file for showing products list in one of the fragments of our project. We will use a custom listview for this achieving this.
Create a new layout file named list_row.xml in res/layout of your project:
list_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="2.5dp"
    android:paddingBottom="2.5dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:orientation="horizontal"
        android:padding="10dp" >

        <!-- ListRow Left sied Thumbnail image -->

        <LinearLayout
            android:id="@+id/thumbnail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginRight="7dip"
            android:padding="2dip" >

            <ImageView
                android:id="@+id/list_image"
                android:layout_width="50dip"
                android:layout_height="50dip"
                android:src="@drawable/ic_basket" />
        </LinearLayout>

        <!-- Title Of Song -->


    
        <TextView
            android:id="@+id/from_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/thumbnail"
            android:text="Pineapple"
            android:textColor="#040404"
            android:textSize="15dip"
            android:typeface="sans" />

        <LinearLayout
            android:id="@+id/cart_plus_minus_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/from_name"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/plist_price_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal|center_vertical"
                android:layout_marginLeft="60dip"
                android:layout_weight="0.23"
                android:paddingRight="5dip"
                android:text="Rs. 200"
                android:textColor="#1d1d1d"
                android:textSize="12dip"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/plist_weight_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal|center_vertical"
                android:paddingRight="25dip"
                android:text="100 gm"
                android:textColor="#343434"
                android:textSize="12dip" />

            <ImageView
                android:id="@+id/cart_minus_img"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_minus" />

            <TextView
                android:id="@+id/cart_product_quantity_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|center_horizontal"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:text="10"
                android:textSize="12dip"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/cart_plus_img"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_plus" />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

The graphical view of the above file we just created would be:
Product List row layout

Now let’s create the layout for listview that will hold the above created layout file for displaying list of products. Create a new layout file named productlist.xml in res/layout folder as below:
productlist.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    android:background="#e1e1e1">

    <ListView
        android:id="@+id/products_listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="@android:color/transparent"
        android:divider="#f55" />
</LinearLayout>

So now we have created two layout files which will be used by a single fragment showing list of products for our Android e-Commerce app.

Similar to the fragment holding product list, we will create many different fragments in our project for showing cart, order history, category wise product filtering, user addresses, order receipt and so on..

Therefore to hold all such fragments together, we will need a side navigation for showing different fragments based on the user’s requirements. For the beginning, we will simply create three tabs inside side navigation drawer i.e Home, Vegetables, Fruits.
Home – This tab will show all the products available in our online store.
Vegetables, Fruits – These are the category tabs showing products filtered based on their Category.

Implementing the side navigation menu for product categories

As we started by created a new blank activity project, there will a layout file already written inside res/layout folder with the name activity_main.xml. We need to modify that file to implement side navigation drawer.

Let’s change the contents of activity_main.xml as follows:
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    android:background="#e1e1e1">

    <ListView
        android:id="@+id/products_listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="@android:color/transparent"
        android:divider="#f55" />

</LinearLayout>

Create a new class in the package com.tutorialsface.models and name it as NavDrawerItem.java with the following content:


public class NavDrawerItem {
	
	private String title;
	private int icon;
	private String count = "0";
	// boolean to set visiblity of the counter
	private boolean isCounterVisible = false;
	
	public NavDrawerItem(){}

	public NavDrawerItem(String title, int icon){
		this.title = title;
		this.icon = icon;
	}
	
	public NavDrawerItem(String title, int icon, boolean isCounterVisible, String count){
		this.title = title;
		this.icon = icon;
		this.isCounterVisible = isCounterVisible;
		this.count = count;
	}
	
	public String getTitle(){
		return this.title;
	}
	
	public int getIcon(){
		return this.icon;
	}
	
	public String getCount(){
		return this.count;
	}
	
	public boolean getCounterVisibility(){
		return this.isCounterVisible;
	}
	
	public void setTitle(String title){
		this.title = title;
	}
	
	public void setIcon(int icon){
		this.icon = icon;
	}
	
	public void setCount(String count){
		this.count = count;
	}
	
	public void setCounterVisibility(boolean isCounterVisible){
		this.isCounterVisible = isCounterVisible;
	}
}

Create NavDrawerListAdapter.java in package com.tutorialsface.listadapters as follows:

package com.tutorialsface.listadapters;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.tutorialsface.ecommerce.R;
import com.tutorialsface.models.NavDrawerItem;

public class NavDrawerListAdapter extends BaseAdapter {
	
	private Context context;
	private ArrayList<NavDrawerItem> navDrawerItems;
	
	public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems){
		this.context = context;
		this.navDrawerItems = navDrawerItems;
	}

	@Override
	public int getCount() {
		return navDrawerItems.size();
	}

	@Override
	public Object getItem(int position) {		
		return navDrawerItems.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater)
                    context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = mInflater.inflate(R.layout.drawer_list_item, null);
        }
         
        ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);
        TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
        TextView txtCount = (TextView) convertView.findViewById(R.id.counter);
         
        imgIcon.setImageResource(navDrawerItems.get(position).getIcon());        
        txtTitle.setText(navDrawerItems.get(position).getTitle());
        
        // displaying count
        // check whether it set visible or not
        if(navDrawerItems.get(position).getCounterVisibility()){
        	txtCount.setText(navDrawerItems.get(position).getCount());
        }else{
        	// hide the counter view
        	txtCount.setVisibility(View.GONE);
        }
        
        return convertView;
	}

}

Edit the strings.xml located at res/values/ folder with following content:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ECommerce</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <!-- Nav Drawer Menu Items -->
    <string-array name="nav_drawer_items">
        <item>Home</item>
        <item>Fruits</item>
        <item>Vegitables</item>
    </string-array>

    <!-- Nav Drawer List Item Icons -->
    <!-- Keep them in order as the titles are in -->
    <array name="nav_drawer_icons">
        <item>@drawable/ic_home</item>
        <item>@drawable/ic_basket</item>
    </array>
    <!-- Content Description -->
    <string name="desc_list_item_icon">Item Icon</string>
    <string name="title_activity_product_details">ProductDetailsActivity</string>

</resources>

Create frgment_navigation_drawer.xml in res/layout as follows:

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccc"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    tools:context="com.tutorialsface.ecommerce.NavigationDrawerFragment" />

Create drawer_list_item.xml in re/layout as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="25dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="12dp"
        android:layout_marginRight="12dp"
        android:contentDescription="@string/desc_list_item_icon"
        android:src="@drawable/ic_home" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/icon"
        android:gravity="center_vertical"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"
        android:paddingRight="40dp"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:textColor="@color/list_item_title" />

    <TextView
        android:id="@+id/counter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="8dp"
        android:textColor="@color/counter_text_color" />

</RelativeLayout>

Update your MainActivity.java with:

package com.tutorialsface.ecommerce;

import java.util.ArrayList;

import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import com.tutorialsface.fragments.ProductsListFragment;
import com.tutorialsface.listadapters.NavDrawerListAdapter;
import com.tutorialsface.models.NavDrawerItem;

public class MainActivity extends ActionBarActivity {
	private DrawerLayout mDrawerLayout;
	private ListView mDrawerList;
	private ActionBarDrawerToggle mDrawerToggle;
	private boolean isCartOpen = false, isProductDetailsOpen = false;
	// nav drawer title
	private CharSequence mDrawerTitle;

	// used to store app title
	private CharSequence mTitle;

	// slide menu items
	private String[] navMenuTitles;
	private TypedArray navMenuIcons;
	private ArrayList<NavDrawerItem> navDrawerItems;
	private NavDrawerListAdapter adapter;

	private String products_category;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mTitle = mDrawerTitle = getTitle();
		// load slide menu items
		navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

		// nav drawer icons from resources
		navMenuIcons = getResources()
				.obtainTypedArray(R.array.nav_drawer_icons);

		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

		navDrawerItems = new ArrayList<NavDrawerItem>();

		// adding nav drawer items to array
		// Home
		navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons
				.getResourceId(0, -1)));
		// Find People
		navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons
				.getResourceId(1, -1)));
		navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons
				.getResourceId(1, -1)));

		// Recycle the typed array
		navMenuIcons.recycle();

		mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

		// setting the nav drawer list adapter
		adapter = new NavDrawerListAdapter(getApplicationContext(),
				navDrawerItems);
		mDrawerList.setAdapter(adapter);

		// enabling action bar app icon and behaving it as toggle button
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		getSupportActionBar().setHomeButtonEnabled(true);
		getSupportActionBar().setTitle("Ecommerce App");
		getSupportActionBar().setIcon(R.drawable.ic_basket);

		getSupportActionBar()
				.setBackgroundDrawable(new ColorDrawable(0xcc3333));
		getSupportActionBar().setDisplayShowTitleEnabled(false);
		getSupportActionBar().setDisplayShowTitleEnabled(true);
		mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
				R.drawable.ic_drawer, // nav menu toggle icon
				R.string.app_name, // nav drawer open - description for
									// accessibility
				R.string.app_name // nav drawer close - description for
									// accessibility
		) {
			public void onDrawerClosed(View view) {
				getSupportActionBar().setTitle(mTitle);
				// calling onPrepareOptionsMenu() to show action bar icons
				supportInvalidateOptionsMenu();
			}

			public void onDrawerOpened(View drawerView) {
				getSupportActionBar().setTitle(mDrawerTitle);
				// calling onPrepareOptionsMenu() to hide action bar icons
				supportInvalidateOptionsMenu();
			}
		};
		mDrawerLayout.setDrawerListener(mDrawerToggle);

		if (savedInstanceState == null) {
			// on first time display view for first nav item
			displayView(0);
		}
	}

	/**
	 * Slide menu item click listener
	 * */
	private class SlideMenuClickListener implements
			ListView.OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			// display view for selected nav drawer item
			displayView(position);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// toggle nav drawer on selecting action bar app icon/title
		if (mDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}
		// Handle action bar actions click
		switch (item.getItemId()) {
		case R.id.action_settings:

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/* *
	 * Called when invalidateOptionsMenu() is triggered
	 */
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// if nav drawer is opened, hide the action items
		boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
		menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
		return super.onPrepareOptionsMenu(menu);
	}

	/**
	 * Diplaying fragment view for selected nav drawer list item
	 * */
	public void displayView(int position) {
		// update the main content by replacing fragments
		Fragment fragment = null;
		switch (position) {
		case 0:
			fragment = new ProductsListFragment();
			break;
		case 1:
			fragment = new ProductsListFragment();
			break;
		case 2:
			fragment = new ProductsListFragment();
			break;

		default:
			break;
		}

		if (fragment != null) {
			FragmentManager fragmentManager = getSupportFragmentManager();
			FragmentTransaction transaction = fragmentManager
					.beginTransaction();
			transaction.addToBackStack(null);
			transaction.replace(R.id.frame_container, fragment, null);
			transaction.commitAllowingStateLoss();

			// update selected item and title, then close the drawer
			mDrawerList.setItemChecked(position, true);
			mDrawerList.setSelection(position);
			setTitle(navMenuTitles[position]);
			mDrawerLayout.closeDrawer(mDrawerList);
		} else {
			// error in creating fragment
			Log.e("MainActivity", "Error in creating fragment");
		}
	}

	@Override
	public void setTitle(CharSequence title) {
		mTitle = title;
		getSupportActionBar().setTitle(mTitle);
	}

	/**
	 * When using the ActionBarDrawerToggle, you must call it during
	 * onPostCreate() and onConfigurationChanged()...
	 */

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		// Sync the toggle state after onRestoreInstanceState has occurred.
		mDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		// Pass any configuration change to the drawer toggls
		mDrawerToggle.onConfigurationChanged(newConfig);
	}

	public String getProducts_category() {
		return products_category;
	}

	public void setProducts_category(String products_category) {
		this.products_category = products_category;
	}

}

Create a new fragment class inside com.tutorialsface.fragments named ProductsListFragment.java with following content:

package com.tutorialsface.fragments;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import com.tutorialsface.ecommerce.MainActivity;
import com.tutorialsface.ecommerce.R;

public class ProductsListFragment extends Fragment {
	private ListView listview;
	MainActivity mainActivity;
	private String productCategory;

	ProgressDialog progessDialog;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mainActivity = (MainActivity) getActivity();

	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		View rootView = inflater
				.inflate(R.layout.productlist, container, false);
		productCategory = mainActivity.getProducts_category();

		listview = (ListView) rootView.findViewById(R.id.products_listview);

		mainActivity.getSupportActionBar().setTitle(productCategory);
		// selecting single ListView item
		ListView lv = listview;
		// listening to single listitem click
		lv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
			}
		});
		return rootView;
	}

	private boolean isProductlistRetrieved = false;

	public boolean isProductlistRetrieved() {
		return isProductlistRetrieved;
	}

	public void setProductlistRetrieved(boolean isProductlistRetrieved) {
		this.isProductlistRetrieved = isProductlistRetrieved;
	}

}

You must have face errors in your layout files and R.java errors in your java files.
To remove these errors, just save the below images in your res/drawable-hd folder and clean the project.
ic_minus

ic_plus

ic_basket

ic_home

ic_trash

ic_drawer

The fragment we just created will show the list of products for our e-commerce android app. From the above code so far, we have created navigation menu with three tabs and one fragment which will show the list of products.

The Final Hierarchy for our eCommerce android app so far is as shown below:

Android Ecommerce  App Tutorial: Project structure Part 1

In the next part, we will create a server to upload products and show the list of products from our server to the android app..

75,964 total views, 162 views today

(Visited 77,171 times, 31 visits today)