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
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.
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
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
沒有留言:
張貼留言