一、适用场景
ListView的每个Item的状态和数据可以进行修改,修改的状态可以保存;修改后的数据要动态的更新反馈给Activity。
二、关键代码
1.CarActivity
该类可以自己定义,这里只是传递一个对象到Adapter中,用于数据的及时反馈。在尝试成功该种方案之前,我考虑的是使用Handler及时的发送消息,来进行数据的及时更新,但是该方案有问题,暂时还没找到解决方法,主要问题是,只要发送消息,就会出现死循环,反馈的数据不断的在变化。如果那位朋友知道如何使用handler实现这种效果,可以和我交流一下,我也来学习学习。
package com.example.chinabuye.activity;
import http.HttpRestClient;
import http.JsonHttpResponseHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import tools.Token;
import tools.UserInfo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import bean.CartGoodBean;
import bean.CartStateBean;
import com.example.chinabuye.R;
import com.example.chinabuye.adapter.CartAdapter;
import com.example.chinabuye.tools.MathTools;
import com.example.chinabuye.tools.PriceTools;
public class CartActivity extends Activity implements OnClickListener {
private static final String TAG = "CartActivity-->>";
private static final int Token_Obsolete = 1;
private static final int Get_NewToken = 2;
private String customerid;
private String accessToken;
private ListView listView_cart;
private CartAdapter adapter;
private List<CartGoodBean> data;
private Button checkOut;
private TextView totalPrice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
customerid = UserInfo.getUserInfoInstance().getUserid();
accessToken = Token.getTokenInstance().getAccessToken();
showCartList(accessToken);
}
/*** 显示购物车产品列表 ***/
private void showCartList(String accessToken) {
HttpRestClient.getCartList(this, customerid, accessToken, new JsonHttpResponseHandler() {
@Override
public void onSuccess(JSONObject response) {
super.onSuccess(response);
try {
if ("true".equals(response.getString("result"))) {
JSONArray rootArray = response.getJSONArray("products");
int size = rootArray.length();
if (size == 0) {
showNoProducLayout();
} else {
showProductLayout(rootArray);
}
} else {
handler.sendEmptyMessage(Token_Obsolete);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
/**** 数据解析 ***/
private void jsonParser(JSONArray rootArray) {
try {
for (int x = 0; x < rootArray.length(); x++) {
JSONObject obj = rootArray.getJSONObject(x);
int number = obj.getInt("qty");
String specifications = obj.getString("sku");
String name = obj.getString("name");
String weight = obj.getString("weight");
String price = obj.getString("price");
String totalWeight = obj.getString("row_weight");
String totalPrice = obj.getString("row_total");
String image = obj.getString("thumbnail");
CartGoodBean bean = new CartGoodBean();
bean.setSku(specifications);
bean.setName(name);
bean.setWeight(weight);
bean.setNumber(number);
bean.setPrice(price);
bean.setImage(image);
bean.setTotalWeight(totalWeight);
bean.setTotalPrice(totalPrice);
data.add(bean);
}
adapter = new CartAdapter(CartActivity.this, data, R.layout.listview_item_cart, totalPrice);
listView_cart.setAdapter(adapter);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
/**** 显示有产品的布局 *******/
private void showProductLayout(JSONArray rootArray) {
setContentView(R.layout.activity_cart);
initView();
jsonParser(rootArray);
}
/**** 初始化有产品时的控件 ***/
private void initView() {
initCommonView();
listView_cart = (ListView) this.findViewById(R.id.listView_cart);
View footerView = getLayoutInflater().inflate(R.layout.listview_footerview_cart, null);
listView_cart.addFooterView(footerView);
checkOut = (Button) this.findViewById(R.id.checkoutButton);
checkOut.setOnClickListener(this);
totalPrice = (TextView) this.findViewById(R.id.total_price);
totalPrice.setText("$0.00");
data = new ArrayList<CartGoodBean>();
}
/****** 初始化标题栏 ***/
private void initCommonView() {
ImageView back = (ImageView) this.findViewById(R.id.back_to_home);
back.setOnClickListener(this);
}
/*** 显示没有产品的布局 *****/
private void showNoProducLayout() {
setContentView(R.layout.activity_cart_none);
TextView goShopping = (TextView) this.findViewById(R.id.cart_goshopping);
goShopping.setOnClickListener(this);
}
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Token_Obsolete:
getNewToken();
break;
case Get_NewToken:
String newAccessToken = msg.obj.toString();
showCartList(newAccessToken);
break;
}
};
};
/** 获取Token ***/
private void getNewToken() {
HttpRestClient.getToken(CartActivity.this, Token.key, Token.secret, new JsonHttpResponseHandler() {
@Override
public void onSuccess(JSONObject response) {
super.onSuccess(response);
try {
if ("true".equals(response.getString("result"))) {
String newAccessToken = response.getString("ACCESSTOKEN");
handler.obtainMessage(Get_NewToken, newAccessToken).sendToTarget();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back_to_home:
Intent intent = new Intent(CartActivity.this, MainActivity.class);
startActivity(intent);
finish();
break;
case R.id.cart_goshopping:
Intent intent2 = new Intent(CartActivity.this, MainActivity.class);
startActivity(intent2);
finish();
break;
case R.id.checkoutButton:
Intent intent3 = new Intent(CartActivity.this, CheckoutActivity.class);
startActivity(intent3);
finish();
break;
default:
break;
}
}
}
2.CartAdapter
这个才是最关键的类,在这里可以进行用户选择状态的保存,用户数据修改状态的保存,以及数据反馈和及时更新
package com.example.chinabuye.adapter;
import http.HttpUrls;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import bean.CartGoodBean;
import bean.CartStateBean;
import com.example.chinabuye.R;
import com.example.chinabuye.activity.CartActivity;
import com.example.chinabuye.app.Options;
import com.example.chinabuye.tools.MathTools;
import com.example.chinabuye.tools.PriceTools;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
public class CartAdapter extends BaseAdapter {
private static final String TAG = "CartAdapter";
private Context context;
private List<CartGoodBean> data;
private int layout;
private TextView totalPrice;
private static HashMap<Integer, CartStateBean> isProductSelected;//状态保存,保存有产品的选中状态和选择的数量
public CartAdapter(Context context, List<CartGoodBean> data, int layout, TextView totalPrice) {
super();
this.context = context;
this.data = data;
this.layout = layout;
this.totalPrice = totalPrice;
isProductSelected = new HashMap<Integer, CartStateBean>();
initDate();
}
public static HashMap<Integer, CartStateBean> getIsProductSelected() {
return isProductSelected;
}
public static void setIsProductSelected(HashMap<Integer, CartStateBean> isProductSelected) {
CartAdapter.isProductSelected = isProductSelected;
}
/***** 初始化最初状态 *******/
private void initDate() {
for (int x = 0; x < data.size(); x++) {
CartStateBean bean = new CartStateBean();
bean.setState(false);
bean.setSelectedNumber(data.get(x).getNumber());
String totalPrice = data.get(x).getTotalPrice();
bean.setTotalPrice(Float.parseFloat(totalPrice));
getIsProductSelected().put(x, bean);
}
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final CartHolder holder;
if (convertView == null) {
holder = new CartHolder();
convertView = LayoutInflater.from(context).inflate(layout, null);
// convertView = LayoutInflater.from(context).inflate(R.layout.listview_item_cart, null);
holder.image = (ImageView) convertView.findViewById(R.id.cart_image);
holder.name = (TextView) convertView.findViewById(R.id.cart_name);
holder.price = (TextView) convertView.findViewById(R.id.cart_price);
holder.pnumber = (TextView) convertView.findViewById(R.id.cart_selectedNum);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cart_select);
holder.specifications = (TextView) convertView.findViewById(R.id.specifications);
holder.reduce = (ImageView) convertView.findViewById(R.id.cart_reduce);
holder.add = (ImageView) convertView.findViewById(R.id.cart_add);
convertView.setTag(holder);
} else {
holder = (CartHolder) convertView.getTag();
}
final CartGoodBean bean = data.get(position);//数据bean
holder.name.setText(bean.getName());
holder.price.setText(PriceTools.formatPrice(bean.getTotalPrice()));//最初的总的价格
holder.pnumber.setText(bean.getNumber() + "");//初始数量
holder.specifications.setText(bean.getSku());
String uri = HttpUrls.PICTURE + bean.getImage();
ImageLoader.getInstance().displayImage(uri, holder.image, Options.getListOptions(), new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
((ImageView) view).setImageBitmap(loadedImage);
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
// TODO Auto-generated method stub
}
});
final CartStateBean stateBean = getIsProductSelected().get(position);//状态bean
holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
stateBean.setState(isChecked);
changePrice();
}
});
holder.reduce.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int num = stateBean.getSelectedNumber();
if (num == 1) {
Toast.makeText(context, "now is only one", 0).show();
} else {
num--;
float price = Float.parseFloat(bean.getPrice());
float totalPrice = MathTools.roundMath(num * price);
String totalPrice2 = PriceTools.formatPrice(totalPrice + "");
holder.price.setText(totalPrice2);
holder.pnumber.setText(num + "");
stateBean.setSelectedNumber(num);
stateBean.setTotalPrice(totalPrice);
}
if (stateBean.getState()) {
changePrice();
}
}
});
holder.add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int num = stateBean.getSelectedNumber();
num++;
float price = Float.parseFloat(bean.getPrice());
float totalPrice = MathTools.roundMath(num * price);
String totalPrice2 = PriceTools.formatPrice(totalPrice + "");
holder.price.setText(totalPrice2);
holder.pnumber.setText(num + "");
stateBean.setSelectedNumber(num);
stateBean.setTotalPrice(totalPrice);
if (stateBean.getState()) {
changePrice();
}
}
});
/*
* 购物车的产品一次请求完毕,不需要下拉刷新,所以data的大小是固定的
*
*/
if (getIsProductSelected().containsKey(position)) {//状态还原
holder.checkBox.setChecked(stateBean.getState());
holder.pnumber.setText(stateBean.getSelectedNumber() + "");
String priceStr = PriceTools.formatPrice(stateBean.getTotalPrice() + "");
holder.price.setText(priceStr);
changePrice();
}
notifyDataSetChanged();
return convertView;
}
private void changePrice() {
float priceNumber = 0.0f;
for (Entry<Integer, CartStateBean> map : isProductSelected.entrySet()) {
CartStateBean bean2 = map.getValue();
if (bean2.getState())
priceNumber += bean2.getTotalPrice();
}
totalPrice.setText(PriceTools.formatPrice(priceNumber + ""));
}
private class CartHolder {
private ImageView image;
private TextView name;
private TextView price;
private CheckBox checkBox;
private TextView specifications;
private ImageView reduce;
private ImageView add;
private TextView pnumber;
}
}
3.效果图
涉及的工具类、业务类、布局文件等并不影响关键代码,主要是原理,理解了个中原理,自己也可以参考写出自己想要的结果。如果发现有什么的问题,请及时批评指正,谢谢!