2016年9月18日 星期日

Android Shopping Cart Tutorial Part 2

Ref :  http://www.androiddom.com/2011/06/android-shopping-cart-tutorial-part-2.html

This tutorial picks up where the first Android Shopping Cart Tutorial leaves off. In this part we will modify the shopping cart to be able to handle multiple quantities of products.

The source code is now available on github.
Update - after following this tutorial, be sure to check out part 3

Before We Begin...

Code often goes through many iterations. And we will do that with the existing shopping cart code from the first Android Shopping Cart Tutorial. In this tutorial we will update the code to handle quantities of products. We will also update the code to be even more object oriented which should make it easier to add more features in the future.


Screenshot of the ShoppingCartActivity displaying quantities


Step 1. Create a New Object - ShoppingCartEntry

In order to add more functionality to our shopping cart, we will need to create a new object. This object will be the ShoppingCartEntry object. This object will contain a reference to the product it holds, and a quantity representing the number of products.

You will be able to modify the quantity for this object, but not the product. The product must be set using the constructor. The code for this new class is listed below.

ShoppingCartEntry.java


package com.dreamdom.tutorials.shoppingcart;

public class ShoppingCartEntry {
 
 private Product mProduct;
 private int mQuantity;
 
 public ShoppingCartEntry(Product product, int quantity) {
  mProduct = product;
  mQuantity = quantity;
 }
 
 public Product getProduct() {
  return mProduct;
 }
 
 public int getQuantity() {
  return mQuantity;
 }
 
 public void setQuantity(int quantity) {
  mQuantity = quantity;
 }

}


Step 2. Modify the ShoppingCartHelper Class

Since we are now using the ShoppingCartEntry objects, we will need to modify our ShoppingCartEntry class. We want to make it easy to add, remove, and change the quantity of products.

Internally, we will change our data structure to be a map of Products mapped to ShoppingCart entries instead of just a list of products. This will make it easy to find the products we want to modify, although the downside is that the display order of the products may change.

The complete code for the modified ShoppingCartHelper is listed below.

ShoppingCartHelper.java



package com.dreamdom.tutorials.shoppingcart;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import android.content.res.Resources;

public class ShoppingCartHelper {
 
 public static final String PRODUCT_INDEX = "PRODUCT_INDEX";
 
 private static List<Product> catalog;
 private static Map<Product, ShoppingCartEntry> cartMap = new HashMap<Product, ShoppingCartEntry>();
 
 public static List<Product> getCatalog(Resources res){
  if(catalog == null) {
   catalog = new Vector<Product>();
   catalog.add(new Product("Dead or Alive", res
     .getDrawable(R.drawable.deadoralive),
     "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
   catalog.add(new Product("Switch", res
     .getDrawable(R.drawable.switchbook),
     "Switch by Chip Heath and Dan Heath", 24.99));
   catalog.add(new Product("Watchmen", res
     .getDrawable(R.drawable.watchmen),
     "Watchmen by Alan Moore and Dave Gibbons", 14.99));
  }
  
  return catalog;
 }
 
 public static void setQuantity(Product product, int quantity) {
  // Get the current cart entry
  ShoppingCartEntry curEntry = cartMap.get(product);
  
  // If the quantity is zero or less, remove the products
  if(quantity <= 0) {
   if(curEntry != null)
    removeProduct(product);
   return;
  }
  
  // If a current cart entry doesn't exist, create one
  if(curEntry == null) {
   curEntry = new ShoppingCartEntry(product, quantity);
   cartMap.put(product, curEntry);
   return;
  }
  
  // Update the quantity
  curEntry.setQuantity(quantity);
 }
 
 public static int getProductQuantity(Product product) {
  // Get the current cart entry
  ShoppingCartEntry curEntry = cartMap.get(product);
  
  if(curEntry != null)
   return curEntry.getQuantity();
  
  return 0;
 }
 
 public static void removeProduct(Product product) {
  cartMap.remove(product);
 }
 
 public static List<Product> getCartList() {
  List<Product> cartList = new Vector<Product>(cartMap.keySet().size());
  for(Product p : cartMap.keySet()) {
   cartList.add(p);
  }
  
  return cartList;
 }
 

}


Step 3. Modify our ProductDetails Layout

Instead of just having a button that says add to cart, lets create an EditText that contains the number of items we want to add. A screenshot of this new layout is shown below

Screenshot of the new Product Details layout.

The complete code for this modified layout is shown below.

productdetails.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_height="fill_parent" android:layout_width="fill_parent"
 android:background="#ffffff" android:orientation="vertical">
 <LinearLayout android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:id="@+id/LinearLayoutHeader"
  android:orientation="horizontal">
  <ImageView android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:id="@+id/ImageViewProduct"
   android:adjustViewBounds="true" android:scaleType="fitXY"
   android:src="@drawable/deadoralive" android:layout_margin="5dip"></ImageView>
  <TextView android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:id="@+id/TextViewProductTitle"
   android:layout_gravity="center" android:layout_margin="5dip"
   android:textSize="26dip" android:text="Dead or Alive"
   android:textColor="#000000"></TextView>

 </LinearLayout>


 <TextView android:layout_height="wrap_content" android:id="@+id/TextViewProductDetails"
  android:layout_width="fill_parent" android:layout_margin="5dip"
  android:layout_weight="1" android:textColor="#000000" android:text="Product description"></TextView>

 <LinearLayout android:layout_height="wrap_content"
  android:layout_width="fill_parent" android:id="@+id/linearLayoutCurrentlyInCart">
  <TextView android:id="@+id/textViewCurrentlyInCart"
   android:layout_width="wrap_content" android:layout_height="wrap_content"
   android:textSize="20dip" android:textColor="#000000" android:text="Currently in Cart:"
   android:layout_margin="5dip"></TextView>
 </LinearLayout>


 <LinearLayout android:layout_height="wrap_content"
  android:layout_width="fill_parent" android:id="@+id/linearLayoutAddLayout"
  android:orientation="horizontal" android:layout_margin="5dip">
  <TextView android:id="@+id/textView1" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:text="Quantity:"
   android:textColor="#000000"></TextView>
  <EditText android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:layout_weight="1"
   android:text="1" android:gravity="right" android:id="@+id/editTextQuantity"
   android:inputType="number"></EditText>
  <Button android:id="@+id/ButtonAddToCart"
   android:layout_gravity="right" android:layout_height="wrap_content"
   android:layout_width="wrap_content" android:text="Set Quantity"></Button>
 </LinearLayout>
</LinearLayout>


Step 4: Modify the ProductDetailsActivity

We no longer want to disable the "Add to Cart" button. So lets remove the code that does that. Listed below is code that we are removing.


// Disable the add to cart button if the item is already in the cart
if(cart.contains(selectedProduct)) {
 addToCartButton.setEnabled(false);
 addToCartButton.setText("Item in Cart");
}

Now we want to add code to handle the new features that we want to add. First, we will want to display the existing quantity of products in the shopping cart. The code to do this is listed below.

// Update the current quantity in the cart
TextView textViewCurrentQuantity = (TextView) findViewById(R.id.textViewCurrentlyInCart);
textViewCurrentQuantity.setText("Currently in Cart: "
  + ShoppingCartHelper.getProductQuantity(selectedProduct));
 


If a product is not in the shopping cart, the ShoppingCart helper will return a value of zero.

Now we want to modify how we are adding products to the shopping cart. We want to set the quantity of products to the value that the user has specified. But we can't trust  the user to have entered a valid input. We will only want to accept Integer inputs of 0 or higher.

So first, we must get a reference to the quantity EditText, next validate the input, and finally add the quantity to the shopping cart. If the input is invalid, we will inform the user of the problem by displaying a message in a toast.

The code to do this is listed below.


// Save a reference to the quantity edit text
final EditText editTextQuantity = (EditText) findViewById(R.id.editTextQuantity);

Button addToCartButton = (Button) findViewById(R.id.ButtonAddToCart);
addToCartButton.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View v) {

  // Check to see that a valid quantity was entered
  int quantity = 0;
  try {
   quantity = Integer.parseInt(editTextQuantity.getText()
     .toString());

   if (quantity < 0) {
    Toast.makeText(getBaseContext(),
      "Please enter a quantity of 0 or higher",
      Toast.LENGTH_SHORT).show();
    return;
   }

  } catch (Exception e) {
   Toast.makeText(getBaseContext(),
     "Please enter a numeric quantity",
     Toast.LENGTH_SHORT).show();

   return;
  }

  // If we make it here, a valid quantity was entered
  ShoppingCartHelper.setQuantity(selectedProduct, quantity);

  // Close the activity
  finish();
 }
});


The complete code for the ProductDetailsActivity is shown below.

ProductDetailsActivity.java 


package com.dreamdom.tutorials.shoppingcart;

import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ProductDetailsActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  setContentView(R.layout.productdetails);

  List<Product> catalog = ShoppingCartHelper.getCatalog(getResources());

  int productIndex = getIntent().getExtras().getInt(
    ShoppingCartHelper.PRODUCT_INDEX);
  final Product selectedProduct = catalog.get(productIndex);

  // Set the proper image and text
  ImageView productImageView = (ImageView) findViewById(R.id.ImageViewProduct);
  productImageView.setImageDrawable(selectedProduct.productImage);
  TextView productTitleTextView = (TextView) findViewById(R.id.TextViewProductTitle);
  productTitleTextView.setText(selectedProduct.title);
  TextView productDetailsTextView = (TextView) findViewById(R.id.TextViewProductDetails);
  productDetailsTextView.setText(selectedProduct.description);

  // Update the current quantity in the cart
  TextView textViewCurrentQuantity = (TextView) findViewById(R.id.textViewCurrentlyInCart);
  textViewCurrentQuantity.setText("Currently in Cart: "
    + ShoppingCartHelper.getProductQuantity(selectedProduct));

  // Save a reference to the quantity edit text
  final EditText editTextQuantity = (EditText) findViewById(R.id.editTextQuantity);

  Button addToCartButton = (Button) findViewById(R.id.ButtonAddToCart);
  addToCartButton.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {

    // Check to see that a valid quantity was entered
    int quantity = 0;
    try {
     quantity = Integer.parseInt(editTextQuantity.getText()
       .toString());

     if (quantity < 0) {
      Toast.makeText(getBaseContext(),
        "Please enter a quantity of 0 or higher",
        Toast.LENGTH_SHORT).show();
      return;
     }

    } catch (Exception e) {
     Toast.makeText(getBaseContext(),
       "Please enter a numeric quantity",
       Toast.LENGTH_SHORT).show();

     return;
    }

    // If we make it here, a valid quantity was entered
    ShoppingCartHelper.setQuantity(selectedProduct, quantity);

    // Close the activity
    finish();
   }
  });

 }

}



Step 3. Modify our ProductDetails Layout

Instead of just having a button that says add to cart, lets create an EditText that contains the number of items we want to add. A screenshot of this new layout is shown below

Screenshot of the new Product Details layout.

The complete code for this modified layout is shown below.

productdetails.xml






沒有留言:

張貼留言