├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── demo ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── android │ │ └── tonyvu │ │ └── sc │ │ └── demo │ │ ├── MainActivity.java │ │ ├── ProductActivity.java │ │ ├── ShoppingCartActivity.java │ │ ├── adapter │ │ ├── CartItemAdapter.java │ │ └── ProductAdapter.java │ │ ├── constant │ │ └── Constant.java │ │ └── model │ │ ├── CartItem.java │ │ └── Product.java │ └── res │ ├── drawable │ ├── htc_one_m8.jpg │ ├── samsung_galaxy_s6.jpg │ └── xiaomi_mi3.jpg │ ├── layout │ ├── activity_cart.xml │ ├── activity_main.xml │ ├── activity_product.xml │ ├── adapter_cart_item.xml │ ├── adapter_product.xml │ ├── cart_footer.xml │ ├── cart_header.xml │ └── product_list_header.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── android │ └── tonyvu │ └── sc │ ├── exception │ ├── ProductNotFoundException.java │ └── QuantityOutOfRangeException.java │ ├── model │ ├── Cart.java │ └── Saleable.java │ └── util │ └── CartHelper.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle files 2 | .gradle/ 3 | build/ 4 | 5 | # Local configuration file (sdk path, etc) 6 | local.properties 7 | 8 | # IntelliJ project files 9 | *.iml 10 | .idea/ 11 | 12 | # Misc 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tony Vu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # android-shoppingcart 2 | 3 | An implementation of android shopping cart library project for Android. 4 | 5 | To use this library, follow these steps: 6 | 7 | Download and include `library` in your dependencies 8 | 9 | dependencies { 10 | // ... 11 | compile project(path: ':library') 12 | } 13 | 14 | For any product that you want to add in your shopping cart, create a class that extends the 15 | `Saleable` interface and implements these 2 methods: 16 | 17 | getName() // must return the product name 18 | getPrice() // must return the product price 19 | 20 | Also override `equals()` and `hashCode()` methods. 21 | 22 | Now from anywhere in your application, you can retrieve the shopping cart with 23 | 24 | Cart cart = CartHelper.getCart(); 25 | 26 | After retrieving the shopping cart, the library provides various methods to manipulate the shopping 27 | cart like adding, removing, updating products or clear the entire shopping cart. 28 | 29 | For an example on how to use this library, please see the `demo` (https://github.com/tonyvu2014/android-shoppingcart/tree/master/demo) app module. 30 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.1.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.android.tonyvu.sc.demo" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile 'com.android.support:appcompat-v7:23.1.0' 24 | compile project(path: ':library') 25 | } 26 | -------------------------------------------------------------------------------- /demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /opt/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.text.SpannableString; 7 | import android.text.style.UnderlineSpan; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.widget.AdapterView; 11 | import android.widget.AdapterView.OnItemClickListener; 12 | import android.widget.ListView; 13 | import android.widget.TextView; 14 | 15 | import com.android.tonyvu.sc.demo.adapter.ProductAdapter; 16 | import com.android.tonyvu.sc.demo.constant.Constant; 17 | import com.android.tonyvu.sc.demo.model.Product; 18 | 19 | public class MainActivity extends AppCompatActivity { 20 | private static final String TAG = "MainActivity"; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_main); 26 | 27 | TextView tvViewShoppingCart = (TextView)findViewById(R.id.tvViewShoppingCart); 28 | SpannableString content = new SpannableString(getText(R.string.shopping_cart)); 29 | content.setSpan(new UnderlineSpan(), 0, content.length(), 0); 30 | tvViewShoppingCart.setText(content); 31 | tvViewShoppingCart.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View v) { 34 | Intent intent = new Intent(MainActivity.this, ShoppingCartActivity.class); 35 | startActivity(intent); 36 | } 37 | }); 38 | 39 | ListView lvProducts = (ListView) findViewById(R.id.lvProducts); 40 | lvProducts.addHeaderView(getLayoutInflater().inflate(R.layout.product_list_header, lvProducts, false)); 41 | 42 | ProductAdapter productAdapter = new ProductAdapter(this); 43 | productAdapter.updateProducts(Constant.PRODUCT_LIST); 44 | 45 | lvProducts.setAdapter(productAdapter); 46 | 47 | lvProducts.setOnItemClickListener(new OnItemClickListener() { 48 | 49 | @Override 50 | public void onItemClick(AdapterView parent, View view, 51 | int position, long id) { 52 | Product product = Constant.PRODUCT_LIST.get(position - 1); 53 | Intent intent = new Intent(MainActivity.this, ProductActivity.class); 54 | Bundle bundle = new Bundle(); 55 | bundle.putSerializable("product", product); 56 | Log.d(TAG, "View product: " + product.getName()); 57 | intent.putExtras(bundle); 58 | startActivity(intent); 59 | } 60 | }); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/ProductActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.text.SpannableString; 7 | import android.text.style.UnderlineSpan; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.view.View.OnClickListener; 11 | import android.widget.ArrayAdapter; 12 | import android.widget.Button; 13 | import android.widget.Spinner; 14 | import android.widget.TextView; 15 | import android.widget.ImageView; 16 | import com.android.tonyvu.sc.demo.constant.Constant; 17 | import com.android.tonyvu.sc.demo.model.Product; 18 | import com.android.tonyvu.sc.model.Cart; 19 | import com.android.tonyvu.sc.util.CartHelper; 20 | 21 | public class ProductActivity extends AppCompatActivity { 22 | private static final String TAG = "ProductActivity"; 23 | 24 | TextView tvProductName; 25 | TextView tvProductDesc; 26 | ImageView ivProductImage; 27 | Spinner spQuantity; 28 | Button bOrder; 29 | Product product; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | 35 | setContentView(R.layout.activity_product); 36 | 37 | Bundle data = getIntent().getExtras(); 38 | product = (Product) data.getSerializable("product"); 39 | 40 | Log.d(TAG, "Product hashCode: " + product.hashCode()); 41 | 42 | //Set Shopping Cart link 43 | setShoppingCartLink(); 44 | 45 | //Retrieve views 46 | retrieveViews(); 47 | 48 | //Set product properties 49 | setProductProperties(); 50 | 51 | //Initialize quantity 52 | initializeQuantity(); 53 | 54 | //On ordering of product 55 | onOrderProduct(); 56 | } 57 | 58 | private void setShoppingCartLink() { 59 | TextView tvViewShoppingCart = (TextView)findViewById(R.id.tvViewShoppingCart); 60 | SpannableString content = new SpannableString(getText(R.string.shopping_cart)); 61 | content.setSpan(new UnderlineSpan(), 0, content.length(), 0); 62 | tvViewShoppingCart.setText(content); 63 | tvViewShoppingCart.setOnClickListener(new OnClickListener() { 64 | @Override 65 | public void onClick(View v) { 66 | Intent intent = new Intent(ProductActivity.this, ShoppingCartActivity.class); 67 | startActivity(intent); 68 | } 69 | }); 70 | } 71 | 72 | private void retrieveViews() { 73 | tvProductName = (TextView) findViewById(R.id.tvProductName); 74 | tvProductDesc = (TextView) findViewById(R.id.tvProductDesc); 75 | ivProductImage = (ImageView) findViewById(R.id.ivProductImage); 76 | spQuantity = (Spinner) findViewById(R.id.spQuantity); 77 | bOrder = (Button) findViewById(R.id.bOrder); 78 | } 79 | 80 | private void setProductProperties() { 81 | tvProductName.setText(product.getName()); 82 | tvProductDesc.setText(product.getDescription()); 83 | ivProductImage.setImageResource(this.getResources().getIdentifier(product.getImageName(), "drawable", this.getPackageName())); 84 | } 85 | 86 | private void initializeQuantity() { 87 | ArrayAdapter dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, Constant.QUANTITY_LIST); 88 | dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 89 | spQuantity.setAdapter(dataAdapter); 90 | } 91 | 92 | private void onOrderProduct() { 93 | bOrder.setOnClickListener(new OnClickListener() { 94 | @Override 95 | public void onClick(View v) { 96 | Cart cart = CartHelper.getCart(); 97 | Log.d(TAG, "Adding product: " + product.getName()); 98 | cart.add(product, Integer.valueOf(spQuantity.getSelectedItem().toString())); 99 | Intent intent = new Intent(ProductActivity.this, ShoppingCartActivity.class); 100 | startActivity(intent); 101 | } 102 | }); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/ShoppingCartActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.DialogInterface; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.util.Log; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.View.OnClickListener; 12 | import android.widget.AdapterView; 13 | import android.widget.Button; 14 | import android.widget.ListView; 15 | import android.widget.TextView; 16 | 17 | import com.android.tonyvu.sc.demo.adapter.CartItemAdapter; 18 | import com.android.tonyvu.sc.demo.constant.Constant; 19 | import com.android.tonyvu.sc.demo.model.CartItem; 20 | import com.android.tonyvu.sc.demo.model.Product; 21 | import com.android.tonyvu.sc.model.Cart; 22 | import com.android.tonyvu.sc.model.Saleable; 23 | import com.android.tonyvu.sc.util.CartHelper; 24 | 25 | import java.math.BigDecimal; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.Map.Entry; 30 | 31 | public class ShoppingCartActivity extends AppCompatActivity { 32 | private static final String TAG = "ShoppingCartActivity"; 33 | 34 | ListView lvCartItems; 35 | Button bClear; 36 | Button bShop; 37 | TextView tvTotalPrice; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_cart); 43 | 44 | lvCartItems = (ListView) findViewById(R.id.lvCartItems); 45 | LayoutInflater layoutInflater = getLayoutInflater(); 46 | 47 | final Cart cart = CartHelper.getCart(); 48 | final TextView tvTotalPrice = (TextView) findViewById(R.id.tvTotalPrice); 49 | tvTotalPrice.setText(Constant.CURRENCY+String.valueOf(cart.getTotalPrice().setScale(2, BigDecimal.ROUND_HALF_UP))); 50 | 51 | lvCartItems.addHeaderView(layoutInflater.inflate(R.layout.cart_header, lvCartItems, false)); 52 | 53 | final CartItemAdapter cartItemAdapter = new CartItemAdapter(this); 54 | cartItemAdapter.updateCartItems(getCartItems(cart)); 55 | 56 | lvCartItems.setAdapter(cartItemAdapter); 57 | 58 | bClear = (Button) findViewById(R.id.bClear); 59 | bShop = (Button) findViewById(R.id.bShop); 60 | 61 | bClear.setOnClickListener(new OnClickListener() { 62 | @Override 63 | public void onClick(View v) { 64 | Log.d(TAG, "Clearing the shopping cart"); 65 | cart.clear(); 66 | cartItemAdapter.updateCartItems(getCartItems(cart)); 67 | cartItemAdapter.notifyDataSetChanged(); 68 | tvTotalPrice.setText(Constant.CURRENCY+String.valueOf(cart.getTotalPrice().setScale(2, BigDecimal.ROUND_HALF_UP))); 69 | } 70 | }); 71 | 72 | bShop.setOnClickListener(new OnClickListener() { 73 | @Override 74 | public void onClick(View v) { 75 | Intent intent = new Intent(ShoppingCartActivity.this, MainActivity.class); 76 | startActivity(intent); 77 | } 78 | }); 79 | 80 | lvCartItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 81 | @Override 82 | public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { 83 | new AlertDialog.Builder(ShoppingCartActivity.this) 84 | .setTitle(getResources().getString(R.string.delete_item)) 85 | .setMessage(getResources().getString(R.string.delete_item_message)) 86 | .setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener() { 87 | @Override 88 | public void onClick(DialogInterface dialog, int which) { 89 | List cartItems = getCartItems(cart); 90 | cart.remove(cartItems.get(position-1).getProduct()); 91 | cartItems.remove(position-1); 92 | cartItemAdapter.updateCartItems(cartItems); 93 | cartItemAdapter.notifyDataSetChanged(); 94 | tvTotalPrice.setText(Constant.CURRENCY+String.valueOf(cart.getTotalPrice().setScale(2, BigDecimal.ROUND_HALF_UP))); 95 | } 96 | }) 97 | .setNegativeButton(getResources().getString(R.string.no), null) 98 | .show(); 99 | return false; 100 | } 101 | }); 102 | 103 | lvCartItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 104 | @Override 105 | public void onItemClick(AdapterView parent, View view, int position, long id) { 106 | Bundle bundle = new Bundle(); 107 | List cartItems = getCartItems(cart); 108 | Product product = cartItems.get(position-1).getProduct(); 109 | Log.d(TAG, "Viewing product: " + product.getName()); 110 | bundle.putSerializable("product", product); 111 | Intent intent = new Intent(ShoppingCartActivity.this, ProductActivity.class); 112 | intent.putExtras(bundle); 113 | startActivity(intent); 114 | } 115 | }); 116 | } 117 | 118 | private List getCartItems(Cart cart) { 119 | List cartItems = new ArrayList(); 120 | Log.d(TAG, "Current shopping cart: " + cart); 121 | 122 | Map itemMap = cart.getItemWithQuantity(); 123 | 124 | for (Entry entry : itemMap.entrySet()) { 125 | CartItem cartItem = new CartItem(); 126 | cartItem.setProduct((Product) entry.getKey()); 127 | cartItem.setQuantity(entry.getValue()); 128 | cartItems.add(cartItem); 129 | } 130 | 131 | Log.d(TAG, "Cart item list: " + cartItems); 132 | return cartItems; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/adapter/CartItemAdapter.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo.adapter; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import android.content.Context; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.BaseAdapter; 12 | import android.widget.TextView; 13 | 14 | import com.android.tonyvu.sc.demo.R; 15 | import com.android.tonyvu.sc.demo.constant.Constant; 16 | import com.android.tonyvu.sc.demo.model.CartItem; 17 | import com.android.tonyvu.sc.model.Cart; 18 | import com.android.tonyvu.sc.util.CartHelper; 19 | 20 | public class CartItemAdapter extends BaseAdapter { 21 | private static final String TAG = "CartItemAdapter"; 22 | 23 | private List cartItems = Collections.emptyList(); 24 | 25 | private final Context context; 26 | 27 | public CartItemAdapter(Context context) { 28 | this.context = context; 29 | } 30 | 31 | public void updateCartItems(List cartItems) { 32 | this.cartItems = cartItems; 33 | notifyDataSetChanged(); 34 | } 35 | 36 | @Override 37 | public int getCount() { 38 | return cartItems.size(); 39 | } 40 | 41 | @Override 42 | public CartItem getItem(int position) { 43 | return cartItems.get(position); 44 | } 45 | 46 | @Override 47 | public long getItemId(int position) { 48 | return position; 49 | } 50 | 51 | @Override 52 | public View getView(final int position, View convertView, ViewGroup parent) { 53 | TextView tvName; 54 | TextView tvUnitPrice; 55 | TextView tvQuantity; 56 | TextView tvPrice; 57 | if (convertView == null) { 58 | convertView = LayoutInflater.from(context) 59 | .inflate(R.layout.adapter_cart_item, parent, false); 60 | tvName = (TextView) convertView.findViewById(R.id.tvCartItemName); 61 | tvUnitPrice = (TextView) convertView.findViewById(R.id.tvCartItemUnitPrice); 62 | tvQuantity = (TextView) convertView.findViewById(R.id.tvCartItemQuantity); 63 | tvPrice = (TextView) convertView.findViewById(R.id.tvCartItemPrice); 64 | convertView.setTag(new ViewHolder(tvName, tvUnitPrice, tvQuantity, tvPrice)); 65 | } else { 66 | ViewHolder viewHolder = (ViewHolder) convertView.getTag(); 67 | tvName = viewHolder.tvCartItemName; 68 | tvUnitPrice = viewHolder.tvCartItemUnitPrice; 69 | tvQuantity = viewHolder.tvCartItemQuantity; 70 | tvPrice = viewHolder.tvCartItemPrice; 71 | } 72 | 73 | final Cart cart = CartHelper.getCart(); 74 | final CartItem cartItem = getItem(position); 75 | tvName.setText(cartItem.getProduct().getName()); 76 | tvUnitPrice.setText(Constant.CURRENCY+String.valueOf(cartItem.getProduct().getPrice().setScale(2, BigDecimal.ROUND_HALF_UP))); 77 | tvQuantity.setText(String.valueOf(cartItem.getQuantity())); 78 | tvPrice.setText(Constant.CURRENCY+String.valueOf(cart.getCost(cartItem.getProduct()).setScale(2, BigDecimal.ROUND_HALF_UP))); 79 | return convertView; 80 | } 81 | 82 | private static class ViewHolder { 83 | public final TextView tvCartItemName; 84 | public final TextView tvCartItemUnitPrice; 85 | public final TextView tvCartItemQuantity; 86 | public final TextView tvCartItemPrice; 87 | 88 | public ViewHolder(TextView tvCartItemName, TextView tvCartItemUnitPrice, TextView tvCartItemQuantity, TextView tvCartItemPrice) { 89 | this.tvCartItemName = tvCartItemName; 90 | this.tvCartItemUnitPrice = tvCartItemUnitPrice; 91 | this.tvCartItemQuantity = tvCartItemQuantity; 92 | this.tvCartItemPrice = tvCartItemPrice; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/adapter/ProductAdapter.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo.adapter; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import android.content.Context; 8 | import android.util.Log; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.BaseAdapter; 13 | import android.widget.ImageView; 14 | import android.widget.TextView; 15 | 16 | import com.android.tonyvu.sc.demo.R; 17 | import com.android.tonyvu.sc.demo.constant.Constant; 18 | import com.android.tonyvu.sc.demo.model.Product; 19 | 20 | public class ProductAdapter extends BaseAdapter { 21 | private static final String TAG = "ProductAdapter"; 22 | 23 | private List products = new ArrayList(); 24 | 25 | private final Context context; 26 | 27 | public ProductAdapter(Context context) { 28 | this.context = context; 29 | } 30 | 31 | public void updateProducts(List products) { 32 | this.products.addAll(products); 33 | notifyDataSetChanged(); 34 | } 35 | 36 | @Override 37 | public int getCount() { 38 | return products.size(); 39 | } 40 | 41 | @Override 42 | public Product getItem(int position) { 43 | return products.get(position); 44 | } 45 | 46 | @Override 47 | public long getItemId(int position) { 48 | return position; 49 | } 50 | 51 | @Override 52 | public View getView(int position, View convertView, ViewGroup parent) { 53 | TextView tvName; 54 | TextView tvPrice; 55 | ImageView ivImage; 56 | if (convertView == null) { 57 | convertView = LayoutInflater.from(context) 58 | .inflate(R.layout.adapter_product, parent, false); 59 | tvName = (TextView) convertView.findViewById(R.id.tvProductName); 60 | tvPrice = (TextView) convertView.findViewById(R.id.tvProductPrice); 61 | ivImage = (ImageView) convertView.findViewById(R.id.ivProductImage); 62 | convertView.setTag(new ViewHolder(tvName, tvPrice, ivImage)); 63 | } else { 64 | ViewHolder viewHolder = (ViewHolder) convertView.getTag(); 65 | tvName = viewHolder.tvProductName; 66 | tvPrice = viewHolder.tvProductPrice; 67 | ivImage = viewHolder.ivProductImage; 68 | } 69 | 70 | final Product product = getItem(position); 71 | tvName.setText(product.getName()); 72 | tvPrice.setText(Constant.CURRENCY+String.valueOf(product.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP))); 73 | Log.d(TAG, "Context package name: " + context.getPackageName()); 74 | ivImage.setImageResource(context.getResources().getIdentifier( 75 | product.getImageName(), "drawable", context.getPackageName())); 76 | // bView.setOnClickListener(new OnClickListener() { 77 | // @Override 78 | // public void onClick(View v) { 79 | // Intent intent = new Intent(context, ProductActivity.class); 80 | // Bundle bundle = new Bundle(); 81 | // bundle.putSerializable("product", product); 82 | // Log.d(TAG, "This product hashCode: " + product.hashCode()); 83 | // intent.putExtras(bundle); 84 | // context.startActivity(intent); 85 | // } 86 | // }); 87 | 88 | return convertView; 89 | } 90 | 91 | private static class ViewHolder { 92 | public final TextView tvProductName; 93 | public final TextView tvProductPrice; 94 | public final ImageView ivProductImage; 95 | 96 | public ViewHolder(TextView tvProductName, TextView tvProductPrice, ImageView ivProductImage) { 97 | this.tvProductName = tvProductName; 98 | this.tvProductPrice = tvProductPrice; 99 | this.ivProductImage = ivProductImage; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/constant/Constant.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo.constant; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.android.tonyvu.sc.demo.model.Product; 8 | 9 | public final class Constant { 10 | public static final List QUANTITY_LIST = new ArrayList(); 11 | 12 | static { 13 | for (int i = 1; i < 11; i++) QUANTITY_LIST.add(i); 14 | } 15 | 16 | public static final Product PRODUCT1 = new Product(1, "Samsung Galaxy S6", BigDecimal.valueOf(199.996), "Worldly looks and top-notch specs make the impressive, metal Samsung Galaxy S6 the Android phone to beat for 2015", "samsung_galaxy_s6"); 17 | public static final Product PRODUCT2 = new Product(2, "HTC One M8", BigDecimal.valueOf(449.9947), "Excellent overall phone. Beautifull, battery life more than 20 hours daily and great customization in any way. 100% configuration on any aspect", "htc_one_m8"); 18 | public static final Product PRODUCT3 = new Product(3, "Xiaomi Mi3", BigDecimal.valueOf(319.998140), "Xiaomi's Mi 3 is a showcase of how Chinese phonemakers can create quality hardware without breaking the bank. If you don't need 4G LTE, and you can get hold of it, this is one of the best smartphones you can buy in its price range.", "xiaomi_mi3"); 19 | 20 | public static final List PRODUCT_LIST = new ArrayList(); 21 | 22 | static { 23 | PRODUCT_LIST.add(PRODUCT1); 24 | PRODUCT_LIST.add(PRODUCT2); 25 | PRODUCT_LIST.add(PRODUCT3); 26 | } 27 | 28 | public static final String CURRENCY = "$"; 29 | } 30 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/model/CartItem.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo.model; 2 | 3 | public class CartItem { 4 | private Product product; 5 | private int quantity; 6 | 7 | public int getQuantity() { 8 | return quantity; 9 | } 10 | 11 | public void setQuantity(int quantity) { 12 | this.quantity = quantity; 13 | } 14 | 15 | public Product getProduct() { 16 | return product; 17 | } 18 | 19 | public void setProduct(Product product) { 20 | this.product = product; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /demo/src/main/java/com/android/tonyvu/sc/demo/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.android.tonyvu.sc.demo.model; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | 6 | import com.android.tonyvu.sc.model.Saleable; 7 | 8 | public class Product implements Saleable, Serializable { 9 | private static final long serialVersionUID = -4073256626483275668L; 10 | 11 | private int pId; 12 | private String pName; 13 | private BigDecimal pPrice; 14 | private String pDescription; 15 | private String pImageName; 16 | 17 | public Product() { 18 | super(); 19 | } 20 | 21 | public Product(int pId, String pName, BigDecimal pPrice, String pDescription, String pImageName) { 22 | setId(pId); 23 | setName(pName); 24 | setPrice(pPrice); 25 | setDescription(pDescription); 26 | setImageName(pImageName); 27 | } 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (o == null) return false; 32 | if (!(o instanceof Product)) return false; 33 | 34 | return (this.pId == ((Product) o).getId()); 35 | } 36 | 37 | public int hashCode() { 38 | final int prime = 31; 39 | int hash = 1; 40 | hash = hash * prime + pId; 41 | hash = hash * prime + (pName == null ? 0 : pName.hashCode()); 42 | hash = hash * prime + (pPrice == null ? 0 : pPrice.hashCode()); 43 | hash = hash * prime + (pDescription == null ? 0 : pDescription.hashCode()); 44 | 45 | return hash; 46 | } 47 | 48 | 49 | public int getId() { 50 | return pId; 51 | } 52 | 53 | public void setId(int id) { 54 | this.pId = id; 55 | } 56 | 57 | @Override 58 | public BigDecimal getPrice() { 59 | return pPrice; 60 | } 61 | 62 | @Override 63 | public String getName() { 64 | return pName; 65 | } 66 | 67 | public void setPrice(BigDecimal price) { 68 | this.pPrice = price; 69 | } 70 | 71 | public void setName(String name) { 72 | this.pName = name; 73 | } 74 | 75 | public String getDescription() { 76 | return pDescription; 77 | } 78 | 79 | public void setDescription(String pDescription) { 80 | this.pDescription = pDescription; 81 | } 82 | 83 | public String getImageName() { 84 | return pImageName; 85 | } 86 | 87 | public void setImageName(String imageName) { 88 | this.pImageName = imageName; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /demo/src/main/res/drawable/htc_one_m8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyvu2014/android-shoppingcart/889e180c540c99bcd7dc8846cdc94099ff30899c/demo/src/main/res/drawable/htc_one_m8.jpg -------------------------------------------------------------------------------- /demo/src/main/res/drawable/samsung_galaxy_s6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyvu2014/android-shoppingcart/889e180c540c99bcd7dc8846cdc94099ff30899c/demo/src/main/res/drawable/samsung_galaxy_s6.jpg -------------------------------------------------------------------------------- /demo/src/main/res/drawable/xiaomi_mi3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyvu2014/android-shoppingcart/889e180c540c99bcd7dc8846cdc94099ff30899c/demo/src/main/res/drawable/xiaomi_mi3.jpg -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_cart.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | 24 | 30 | 31 | 40 | 41 | 48 | 49 | 57 | 58 | 59 | 66 | 67 |