1.购物车数据存储器
1.把购物车数据存储到本地,转换成json字符串使用SP存储
2.PreferencesUtils
package cniao5.com.cniao5shop.utils;
import android.content.Context;
import android.content.SharedPreferences;
/**
* PreferencesUtils, easy to get or put data
* <ul>
* <strong>Preference Name</strong>
* <li>you can change preference name by {@link #PREFERENCE_NAME}</li>
* </ul>
* <ul>
* <strong>Put Value</strong>
* <li>put string {@link #putString(Context, String, String)}</li>
* <li>put int {@link #putInt(Context, String, int)}</li>
* <li>put long {@link #putLong(Context, String, long)}</li>
* <li>put float {@link #putFloat(Context, String, float)}</li>
* <li>put boolean {@link #putBoolean(Context, String, boolean)}</li>
* </ul>
* <ul>
* <strong>Get Value</strong>
* <li>get string {@link #getString(Context, String)}, {@link #getString(Context, String, String)}</li>
* <li>get int {@link #getInt(Context, String)}, {@link #getInt(Context, String, int)}</li>
* <li>get long {@link #getLong(Context, String)}, {@link #getLong(Context, String, long)}</li>
* <li>get float {@link #getFloat(Context, String)}, {@link #getFloat(Context, String, float)}</li>
* <li>get boolean {@link #getBoolean(Context, String)}, {@link #getBoolean(Context, String, boolean)}</li>
* </ul>
*
*/
public class PreferencesUtils {
public static String PREFERENCE_NAME = "Cniao_Pref_Common";
/**
* put string preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putString(Context context, String key, String value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value);
return editor.commit();
}
/**
* get string preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or null. Throws ClassCastException if there is a preference with this
* name that is not a string
* @see #getString(Context, String, String)
*/
public static String getString(Context context, String key) {
return getString(context, key, null);
}
/**
* get string preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a string
*/
public static String getString(Context context, String key, String defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getString(key, defaultValue);
}
/**
* put int preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putInt(Context context, String key, int value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(key, value);
return editor.commit();
}
/**
* get int preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a int
* @see #getInt(Context, String, int)
*/
public static int getInt(Context context, String key) {
return getInt(context, key, -1);
}
/**
* get int preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a int
*/
public static int getInt(Context context, String key, int defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getInt(key, defaultValue);
}
/**
* put long preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putLong(Context context, String key, long value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putLong(key, value);
return editor.commit();
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a long
* @see #getLong(Context, String, long)
*/
public static long getLong(Context context, String key) {
return getLong(context, key, -1);
}
/**
* get long preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a long
*/
public static long getLong(Context context, String key, long defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getLong(key, defaultValue);
}
/**
* put float preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putFloat(Context context, String key, float value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putFloat(key, value);
return editor.commit();
}
/**
* get float preferences
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
* name that is not a float
* @see #getFloat(Context, String, float)
*/
public static float getFloat(Context context, String key) {
return getFloat(context, key, -1);
}
/**
* get float preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a float
*/
public static float getFloat(Context context, String key, float defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getFloat(key, defaultValue);
}
/**
* put boolean preferences
*
* @param context
* @param key The name of the preference to modify
* @param value The new value for the preference
* @return True if the new values were successfully written to persistent storage.
*/
public static boolean putBoolean(Context context, String key, boolean value) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(key, value);
return editor.commit();
}
/**
* get boolean preferences, default is false
*
* @param context
* @param key The name of the preference to retrieve
* @return The preference value if it exists, or false. Throws ClassCastException if there is a preference with this
* name that is not a boolean
* @see #getBoolean(Context, String, boolean)
*/
public static boolean getBoolean(Context context, String key) {
return getBoolean(context, key, false);
}
/**
* get boolean preferences
*
* @param context
* @param key The name of the preference to retrieve
* @param defaultValue Value to return if this preference does not exist
* @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
* this name that is not a boolean
*/
public static boolean getBoolean(Context context, String key, boolean defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
return settings.getBoolean(key, defaultValue);
}
}
3.JSONUtil
/*
*JSONUtil.java
*Created on 2014-9-29 上午9:54 by Ivan
*Copyright(c)2014 Guangzhou Onion Information Technology Co., Ltd.
*http://www.cniao5.com
*/
package cniao5.com.cniao5shop.utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.lang.reflect.Type;
/**
* Created by Ivan on 14-9-29.
* Copyright(c)2014 Guangzhou Onion Information Technology Co., Ltd.
* http://www.cniao5.com
*/
public class JSONUtil {
private static Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
public static Gson getGson(){
return gson;
}
public static <T> T fromJson(String json,Class<T> clz){
return gson.fromJson(json,clz);
}
public static <T> T fromJson(String json,Type type){
return gson.fromJson(json,type);
}
public static String toJSON(Object object){
return gson.toJson(object);
}
}
4.数据存储器 CartProvider
package cniao5.com.cniao5shop.utils;
import android.content.Context;
import android.util.SparseArray;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.List;
import cniao5.com.cniao5shop.bean.ShoppingCart;
/**
* Created by <a href="http://www.cniao5.com">菜鸟窝</a>
* 一个专业的Android开发在线教育平台
*/
public class CartProvider {
public static final String CART_JSON="cart_json";
//相当于HasMap
private SparseArray<ShoppingCart> datas =null;
private Context mContext;
public CartProvider(Context context){
mContext = context;
datas = new SparseArray<>(10);
listToSparse();
}
//添加数据
public void put(ShoppingCart cart){
ShoppingCart temp = datas.get(cart.getId().intValue());
//判断该商品是否已经存在
if(temp !=null){
temp.setCount(temp.getCount()+1);
}
else{
temp = cart;
temp.setCount(1);
}
datas.put(cart.getId().intValue(),temp);
commit();
}
//更新数据
public void update(ShoppingCart cart){
datas.put(cart.getId().intValue(),cart);
commit();
}
//删除数据
public void delete(ShoppingCart cart){
datas.delete(cart.getId().intValue());
commit();
}
//获取所有数据
public List<ShoppingCart> getAll(){
return getDataFromLocal();
}
//保存数据到本地
public void commit(){
List<ShoppingCart> carts = sparseToList();
PreferencesUtils.putString(mContext,CART_JSON,JSONUtil.toJSON(carts));
}
private List<ShoppingCart> sparseToList(){
int size = datas.size();
List<ShoppingCart> list = new ArrayList<>(size);
for (int i=0;i<size;i++){
list.add(datas.valueAt(i));
}
return list;
}
//将本地数据存放在SparseArray
private void listToSparse(){
List<ShoppingCart> carts = getDataFromLocal();
if(carts!=null && carts.size()>0){
for (ShoppingCart cart:
carts) {
datas.put(cart.getId().intValue(),cart);
}
}
}
//从本地获取数据转化成对象
public List<ShoppingCart> getDataFromLocal(){
String json = PreferencesUtils.getString(mContext,CART_JSON);
List<ShoppingCart> carts =null;
if(json !=null ){
carts = JSONUtil.fromJson(json,new TypeToken<List<ShoppingCart>>(){}.getType());
}
return carts;
}
}
(1)SparseArray 代替 HasMap
2.显示购物车商品
1.布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp">
</android.support.v7.widget.RecyclerView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="#802f4f4f"
android:gravity="center_vertical"
>
<CheckBox
android:id="@+id/checkbox_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:checked="true"
android:text="全选"
style="@style/customCheckbox"/>
<TextView
android:id="@+id/txt_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/checkbox_all"
android:layout_marginLeft="40dp"
android:layout_centerVertical="true"
android:textSize="30dp"
android:text="合计"/>
<Button
android:id="@+id/btn_order"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:minHeight="60dp"
android:minWidth="120dp"
android:text="去结算"
style="@style/bigRedButton"/>
<Button
android:id="@+id/btn_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:visibility="gone"
android:minHeight="60dp"
android:minWidth="120dp"
android:text="删除"
style="@style/bigRedButton"/>
</RelativeLayout>
</RelativeLayout>
3.购物车商品选择和总价统计
4.购物车编辑实现
1.CartAdapter
package cniao5.com.cniao5shop.adapter;
import android.content.Context;
import android.net.Uri;
import android.text.Html;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import com.facebook.drawee.view.SimpleDraweeView;
import java.util.Iterator;
import java.util.List;
import cniao5.com.cniao5shop.R;
import cniao5.com.cniao5shop.bean.ShoppingCart;
import cniao5.com.cniao5shop.utils.CartProvider;
import cniao5.com.cniao5shop.widget.NumberAddSubView;
/**
*购物车Adapter
*/
public class CartAdapter extends SimpleAdapter<ShoppingCart> implements BaseAdapter.OnItemClickListener {
public static final String TAG="CartAdapter";
private CheckBox checkBox;
private TextView textView;
private CartProvider cartProvider;
public CartAdapter(Context context, List<ShoppingCart> datas, final CheckBox checkBox,TextView tv) {
super(context, R.layout.template_cart, datas);
setCheckBox(checkBox);
setTextView(tv);
cartProvider = new CartProvider(context);
setOnItemClickListener(this);
showTotalPrice();
}
@Override
protected void convert(BaseViewHolder viewHoder, final ShoppingCart item) {
viewHoder.getTextView(R.id.text_title).setText(item.getName());
viewHoder.getTextView(R.id.text_price).setText("¥"+item.getPrice());
SimpleDraweeView draweeView = (SimpleDraweeView) viewHoder.getView(R.id.drawee_view);
draweeView.setImageURI(Uri.parse(item.getImgUrl()));
CheckBox checkBox = (CheckBox) viewHoder.getView(R.id.checkbox);
checkBox.setChecked(item.isChecked());
NumberAddSubView numberAddSubView = (NumberAddSubView) viewHoder.getView(R.id.num_control);
numberAddSubView.setValue(item.getCount());
numberAddSubView.setOnButtonClickListener(new NumberAddSubView.OnButtonClickListener() {
@Override
public void onButtonAddClick(View view, int value) {
item.setCount(value);
cartProvider.update(item);
showTotalPrice();
}
@Override
public void onButtonSubClick(View view, int value) {
item.setCount(value);
cartProvider.update(item);
showTotalPrice();
}
});
}
private float getTotalPrice(){
float sum=0;
if(!isNull())
return sum;
for (ShoppingCart cart:
datas) {
if(cart.isChecked())
sum += cart.getCount()*cart.getPrice();
}
return sum;
}
//获取总价
public void showTotalPrice(){
float total = getTotalPrice();
textView.setText(Html.fromHtml("合计 ¥<span style='color:#eb4f38'>" + total + "</span>"), TextView.BufferType.SPANNABLE);
}
private boolean isNull(){
return (datas !=null && datas.size()>0);
}
@Override
public void onItemClick(View view, int position) {
ShoppingCart cart = getItem(position);
cart.setIsChecked(!cart.isChecked());
notifyItemChanged(position);
checkListen();
showTotalPrice();
}
private void checkListen() {
int count = 0;
int checkNum = 0;
if (datas != null) {
count = datas.size();
for (ShoppingCart cart : datas) {
if (!cart.isChecked()) {
checkBox.setChecked(false);
break;
} else {
checkNum = checkNum + 1;
}
}
if (count == checkNum) {
checkBox.setChecked(true);
}
}
}
public void checkAll_None(boolean isChecked){
if(!isNull())
return ;
int i=0;
for (ShoppingCart cart :datas){
cart.setIsChecked(isChecked);
notifyItemChanged(i);
i++;
}
}
public void delCart(){
if(!isNull())
return ;
// for (ShoppingCart cart : datas){
//
// if(cart.isChecked()){
// int position = datas.indexOf(cart);
// cartProvider.delete(cart);
// datas.remove(cart);
// notifyItemRemoved(position);
// }
// }
for(Iterator iterator = datas.iterator();iterator.hasNext();){
ShoppingCart cart = (ShoppingCart) iterator.next();
if(cart.isChecked()){
int position = datas.indexOf(cart);
cartProvider.delete(cart);
iterator.remove();
notifyItemRemoved(position);
}
}
}
public void setTextView(TextView textview){
this.textView = textview;
}
public void setCheckBox(CheckBox ck){
this.checkBox = ck;
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAll_None(checkBox.isChecked());
showTotalPrice();
}
});
}
}
package cniao5.com.cniao5shop.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.OnClick;
import java.util.List;
import cniao5.com.cniao5shop.MainActivity;
import cniao5.com.cniao5shop.R;
import cniao5.com.cniao5shop.adapter.CartAdapter;
import cniao5.com.cniao5shop.adapter.decoration.DividerItemDecoration;
import cniao5.com.cniao5shop.bean.ShoppingCart;
import cniao5.com.cniao5shop.utils.CartProvider;
import cniao5.com.cniao5shop.widget.CnToolbar;
/**
* Created by Ivan on 15/9/22.
*/
public class CartFragment extends Fragment implements View.OnClickListener{
public static final int ACTION_EDIT=1; //编辑状态
public static final int ACTION_CAMPLATE=2;//完成状态
@ViewInject(R.id.recycler_view)
private RecyclerView mRecyclerView;
@ViewInject(R.id.checkbox_all)
private CheckBox mCheckBox;
@ViewInject(R.id.txt_total)
private TextView mTextTotal;
@ViewInject(R.id.btn_order)
private Button mBtnOrder;
@ViewInject(R.id.btn_del)
private Button mBtnDel;
private CnToolbar mToolbar;
private CartAdapter mAdapter;
private CartProvider cartProvider;
//改写后的TabFragment只会首次执行该方法
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_cart,container,false);
ViewUtils.inject(this,view);
cartProvider = new CartProvider(getContext());
showData();
return view;
}
@OnClick(R.id.btn_del)
public void delCart(View view){
mAdapter.delCart();
}
//显示数据
private void showData(){
List<ShoppingCart> carts = cartProvider.getAll();
mAdapter = new CartAdapter(getContext(),carts,mCheckBox,mTextTotal);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL_LIST));
}
public void refData(){
mAdapter.clear();
List<ShoppingCart> carts = cartProvider.getAll();
mAdapter.addData(carts);
mAdapter.showTotalPrice();
}
//在Fragment中获取Activity方法
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof MainActivity){
MainActivity activity = (MainActivity) context;
mToolbar = (CnToolbar) activity.findViewById(R.id.toolbar);
changeToolbar();
}
}
//改变ToolBar
public void changeToolbar(){
mToolbar.hideSearchView();
mToolbar.showTitleView();
mToolbar.setTitle(R.string.cart);
mToolbar.getRightButton().setVisibility(View.VISIBLE);
mToolbar.setRightButtonText("编辑");
mToolbar.getRightButton().setOnClickListener(this);
mToolbar.getRightButton().setTag(ACTION_EDIT);
}
private void showDelControl(){
mToolbar.getRightButton().setText("完成");
mTextTotal.setVisibility(View.GONE);
mBtnOrder.setVisibility(View.GONE);
mBtnDel.setVisibility(View.VISIBLE);
mToolbar.getRightButton().setTag(ACTION_CAMPLATE);
mAdapter.checkAll_None(false);
mCheckBox.setChecked(false);
}
private void hideDelControl(){
mTextTotal.setVisibility(View.VISIBLE);
mBtnOrder.setVisibility(View.VISIBLE);
mBtnDel.setVisibility(View.GONE);
mToolbar.setRightButtonText("编辑");
mToolbar.getRightButton().setTag(ACTION_EDIT);
mAdapter.checkAll_None(true);
mAdapter.showTotalPrice();
mCheckBox.setChecked(true);
}
@Override
public void onClick(View v) {
int action = (int) v.getTag();
if(ACTION_EDIT == action){
showDelControl();
}
else if(ACTION_CAMPLATE == action){
hideDelControl();
}
}
}