购物车
最近写了一个商城APP中常用功能“购物车”
购物车效果图如下:
购物车功能需求如下:
下面是购物车主activity“MainActivity”代码:
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Response;
import shop.hsy.com.shopcar.adapter.ShopAdapter;
import shop.hsy.com.shopcar.entity.ResultModel;
import shop.hsy.com.shopcar.entity.Shopping;
import shop.hsy.com.shopcar.net.ShopCarNet;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ListView shop_list;
private ShopAdapter shopAdapter;
private TextView prices;
private CheckBox all_checks;
private TextView settlement;
private TextView delete_text;
private Response<ResultModel<List<Shopping>>> modelResponse;//接口请求回来的数据
private List<Shopping> shoppingList = new ArrayList<>();//重新整合后的数据
private ProgressDialog progressDialog;
private int a=0;//此字段非常重要,用来解决全选与单选冲突
private int b=1;//此字段非常重要,用来解决字段a与全选冲突
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage("······");
initview();
}
private void initview(){
shop_list = (ListView) findViewById(R.id.shop_list);
shopAdapter = new ShopAdapter(MainActivity.this);
shop_list.setAdapter(shopAdapter);
all_checks = (CheckBox) findViewById(R.id.all_checks);//全选
prices = (TextView) findViewById(R.id.prices);//价格
settlement = (TextView) findViewById(R.id.settlement);//结算
delete_text = (TextView) findViewById(R.id.delete_text);//删除
settlement.setOnClickListener(this);
delete_text.setOnClickListener(this);
getShopData(22+"");
AllChecks();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.settlement: //结算
Settlement();
break;
case R.id.delete_text: //删除
AllDelete();
break;
}
}
/**
* 数据接口请求
* @param mid
*/
private void getShopData(final String mid){
new Thread(new Runnable() {
@Override
public void run() {
try {
modelResponse = ShopCarNet.getShop(mid).execute();
Message message = mhandler.obtainMessage();
message.what = 0;
message.sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0:
if(modelResponse!=null){
if(modelResponse.body()!=null){
if(modelResponse.body().getData()!=null
&&modelResponse.body().getData().size()>0){
for (Shopping shop:modelResponse.body().getData()) {
shop.setChecks(false);//给商品添加为选中状态
shoppingList.add(shop);
}
shopAdapter.addItem(shoppingList);
shopAdapter.notifyDataSetChanged();
}
}
}else{
Log.e("mainactivity","没有数据");
}
break;
}
}
};
/**
* 全选check监听
*/
public void AllChecks(){
all_checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
progressDialog.show();
if(b==0){
a=0;b=1;
}
if(a==0) {//解决单选与全选冲突
if (isChecked) {//true:全选被选中,false:全选取消
double AllPrice = 0;
for (Shopping shop : shoppingList) {
shop.setChecks(true);//改变商品选中状态
AllPrice = AllPrice + Double.valueOf(shop.p_price) * shop.p_number;//计算商品总价
}
prices.setText("¥" + AllPrice);//显示总价
} else {
b=0;
for (Shopping shop : shoppingList) {
shop.setChecks(false);//改变商品未选中状态
}
prices.setText("¥0.0");//价格改为0
}
shopAdapter.clear();
shopAdapter.addItem(shoppingList);//添加改编后的数据到list的Adapter
shopAdapter.notifyDataSetChanged();//刷新列表
}
a=0;
if (progressDialog != null) progressDialog.cancel();
}
});
}
/**
* 选中,加减方法
* @param checks 是否被选中
* @param count 被选中的商品id
* @param number 被选中商品的数量
*/
public void UpView(boolean checks, int count,int number){
progressDialog.show();
double AllPrice = 0;
int size = 0 ;//用来计数,判断数据是否被全部选中
for (Shopping shop:shoppingList) {
if(shop.p_id == count){//查找被选中商品id
shop.setChecks(checks);//改变商品集合shoppingList中的选中状态
shop.p_number = number;//同时修改商品数量
}
if(shop.isChecks()){//判断商品是否被选中,如被选中计算价格
size++;
AllPrice =AllPrice + Double.valueOf(shop.p_price) * shop.p_number;//得到被选中商品的总价格
}
}
shopAdapter.clear();
shopAdapter.addItem(shoppingList);
shopAdapter.notifyDataSetChanged();
prices.setText("¥"+AllPrice);
if(size == shoppingList.size()){
all_checks.setChecked(true);//是全部被选中,改变全选check状态为选中
}else{
a = 1;//a=1表示all_checks监听中方法不执行
if(!all_checks.isChecked()) a=0;//all_checks未被选中给a赋值0让all_checks的监听中的方法继续执行
all_checks.setChecked(false);//不是,继续维持未选中状态
}
if (progressDialog != null) progressDialog.cancel();
}
/**
* 结算方法
*/
public void Settlement(){
List<Integer> settlement_list = new ArrayList<>();
final List<Shopping> new_list = new ArrayList<>();
for (Shopping shop:shoppingList) {
if(shop.isChecks()){
settlement_list.add(shop.p_id);//取出被选中商品id加入新的list准备掉接口完成结算
}else{
new_list.add(shop);//剩余商品形成新的购物车列表等待显示
}
}
if(settlement_list.size()==0){
Toast.makeText(MainActivity.this,"请选中至少一个商品后在结算",Toast.LENGTH_SHORT).show();
return;
}
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("提示").setMessage("总共"+settlement_list.size()+"个商品,共"+prices.getText().toString()+"元,是否要结算?");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//在这里调结算接口把delete_list传给后台
shoppingList = new_list;
shopAdapter.clear();
shopAdapter.addItem(shoppingList);
shopAdapter.notifyDataSetChanged();
prices.setText("¥0.0");
dialog.cancel();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create().show();
}
/**
* 删除方法
* 该方法类似结算方法
*/
public void AllDelete(){
List<Integer> delete_list = new ArrayList<>();
final List<Shopping> new_list = new ArrayList<>();
for (Shopping shop:shoppingList) {
if(shop.isChecks()){
delete_list.add(shop.p_id);
}else{
new_list.add(shop);
}
}
if(delete_list.size()==0){
Toast.makeText(MainActivity.this,"请选中至少一个商品后在删除",Toast.LENGTH_SHORT).show();
return;
}
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("提示").setMessage("确定要删除这"+delete_list.size()+"个商品?");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//在这里调删除接口把delete_list传给后台
shoppingList = new_list;
shopAdapter.clear();
shopAdapter.addItem(shoppingList);
shopAdapter.notifyDataSetChanged();
prices.setText("¥0.0");
dialog.cancel();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create().show();
}
}
MainActivity的布局文件很简单:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="shop.hsy.com.shopcar.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:background="@android:color/white"
android:layout_height="45dp"
android:id="@+id/linearLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="购物车"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/linearLayout"
android:layout_above="@+id/relativeLayout">
<ListView
android:id="@+id/shop_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
android:orientation="horizontal"
android:id="@+id/relativeLayout">
<CheckBox
android:id="@+id/all_checks"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:button="@drawable/radio_button_bg"
android:textSize="16sp"
android:textColor="#FF000000"
android:text=" 全选"/>
<TextView
android:id="@+id/delete_text"
android:layout_width="70dp"
android:layout_height="match_parent"
android:text="删除"
android:textSize="16sp"
android:textColor="@android:color/white"
android:background="#FFFA4F4F"
android:gravity="center"
android:layout_alignParentRight="true" />
<TextView
android:id="@+id/settlement"
android:layout_width="70dp"
android:layout_height="match_parent"
android:text="结算"
android:textSize="16sp"
android:textColor="@android:color/white"
android:layout_marginLeft="10dp"
android:background="#FFFFB11C"
android:gravity="center"
android:layout_toLeftOf="@+id/delete_text" />
<TextView
android:id="@+id/prices"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="¥0.0"
android:textSize="16sp"
android:textColor="#FFFA4F4F"
android:layout_alignParentTop="true"
android:layout_toStartOf="@+id/settlement" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="合计:"
android:textSize="16sp"
android:textColor="#FF000000"
android:layout_alignParentTop="true"
android:layout_toStartOf="@+id/prices" />
</RelativeLayout>
</RelativeLayout>
购物车Adapter代码“ShopAdapter”,由于我继承一个BaseAtapter,所以这个Adapter我只需要处理getView方法:
import android.content.Context;
import android.graphics.Paint;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.nostra13.universalimageloader.core.ImageLoader;
import shop.hsy.com.shopcar.MainActivity;
import shop.hsy.com.shopcar.MyApplication;
import shop.hsy.com.shopcar.R;
import shop.hsy.com.shopcar.entity.Shopping;
/**
* Created by hsy on 2016/11/10.
*/
public class ShopAdapter extends BaseAdapter {
private LayoutInflater inflater;
private Context context;
private MainActivity mainActivity;
public ShopAdapter(Context context) {
this.context = context;
mainActivity = (MainActivity)context;
inflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.shop_item, parent, false);
holder.checks = (CheckBox) convertView.findViewById(R.id.checks);//选择框
holder.p_img1 = (ImageView) convertView.findViewById(R.id.p_img1);//商品缩略图
holder.p_name = (TextView) convertView.findViewById(R.id.p_name);//名称
holder.p_price = (TextView) convertView.findViewById(R.id.p_price);//价格
holder.p_mprice = (TextView) convertView.findViewById(R.id.p_mprice);//过时价格
holder.p_discount = (TextView) convertView.findViewById(R.id.p_discount);//折扣
holder.p_news = (TextView) convertView.findViewById(R.id.p_news);//成色
holder.p_stock = (TextView) convertView.findViewById(R.id.p_stock);//库存
holder.p_number = (TextView) convertView.findViewById(R.id.p_number);//数量
holder.minus = (ImageView) convertView.findViewById(R.id.minus);//减
holder.add = (ImageView) convertView.findViewById(R.id.add);//加
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Shopping shopping = (Shopping) getItem(position);
if (!TextUtils.isEmpty(shopping.p_img1)) {
ImageLoader.getInstance().displayImage(shopping.p_img1, holder.p_img1, MyApplication.option);
}else {
holder.p_img1.setImageResource(R.mipmap.ic_launcher);
}
holder.p_name.setText(shopping.p_name);
holder.p_price.setText(shopping.p_price);
holder.p_mprice.setText(shopping.p_mprice);
holder.p_discount.setText(shopping.p_discount);
holder.p_news.setText(shopping.p_news);
holder.p_number.setText(shopping.p_number+"");
holder.p_stock.setText(shopping.p_stock);
holder.checks.setChecked(shopping.isChecks());
holder.p_mprice.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
//全选监听
holder.checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mainActivity.UpView(isChecked, shopping.p_id, shopping.p_number);
}
});
//数量减
holder.minus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int minus = 0;
if(shopping.p_number>1) {
minus = shopping.p_number-1;
mainActivity.UpView(shopping.isChecks(), shopping.p_id, minus);
}else{
Toast.makeText(context,"数量不能再少了",Toast.LENGTH_SHORT).show();
}
}
});
//数量加
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainActivity.UpView(shopping.isChecks(),shopping.p_id,(shopping.p_number+1));
}
});
return convertView;
}
private class ViewHolder {
private CheckBox checks;
private ImageView p_img1;
private TextView p_name;
private TextView p_price;
private TextView p_mprice;
private TextView p_discount;
private TextView p_news;
private TextView p_stock;
private TextView p_number;
private ImageView minus;
private ImageView add;
}
}
Adapter布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@android:color/white"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/checks"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/radio_button_bg"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"/>
<ImageView
android:id="@+id/p_img1"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_gravity="center_vertical"
android:src="@mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/p_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#FF000000"
android:text=""/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/p_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFA3C3C"
android:textSize="14sp"
android:text=""/>
<TextView
android:id="@+id/p_mprice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="7dp"
android:textColor="#FF9B9B9B"
android:textSize="10sp"
android:text=""/>
<TextView
android:id="@+id/p_discount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:gravity="center"
android:textColor="@android:color/white"
android:background="#FF6EDAED"
android:text=""/>
<TextView
android:id="@+id/p_news"
android:layout_width="wrap_content"
android:textSize="10sp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:gravity="center"
android:layout_marginLeft="4dp"
android:textColor="@android:color/white"
android:background="#FF6EDAED"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/p_stock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF9B9B9B"
android:textSize="11sp"
android:text=""/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginRight="5dp"
android:layout_alignParentRight="true">
<ImageView
android:id="@+id/minus"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@mipmap/btn_minus"/>
<TextView
android:id="@+id/p_number"
android:layout_width="23dp"
android:layout_height="16dp"
android:gravity="center"
android:background="#FFF1F1F1"
android:textSize="9sp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:textColor="#FF000000"
android:text="1"/>
<ImageView
android:id="@+id/add"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@mipmap/btn_plus"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
至此,购物车功能就实现了,这里最主要的就是MainActivity中的UpView方法,其次就是CheckBox的监听(setOnCheckedChangeListener);
注意 :在MainActivity中我用了a和b两个字段来解决Adapter中的CheckBox监听和Activity中的CheckBox监听冲突问题。
欢迎各位点评提问,O(∩_∩)O谢谢!