Android購物車項(xiàng)目快速開發(fā)
購物車項(xiàng)目,業(yè)務(wù)需要實(shí)現(xiàn)了一個購物車的項(xiàng)目,簡單的了解下實(shí)現(xiàn)邏輯:數(shù)據(jù)計算等是在Adapter中計算出來的,通過在Adapter中計算出來的數(shù)據(jù)就可以回調(diào)到Activity中進(jìn)行訂單操作等功能業(yè)務(wù)邏輯,每一個店鋪產(chǎn)生的數(shù)據(jù)是走一條流程的,(業(yè)務(wù)需求:不是作為一個類似淘寶,京東的平臺數(shù)據(jù)又由平臺分發(fā),所以我們實(shí)現(xiàn)的是一對一的客戶交易的交易流程)接著往下看:
1.界面使用到的控件
goodsAdapter = new GoodsCarAdapter(ShopCarAvtivity.this, result);
lv_refresh.setAdapter(goodsAdapter);
goodsAdapter.setCheckInterface(ShopCarAvtivity.this);// 關(guān)鍵步驟1,設(shè)置復(fù)選框接口
goodsAdapter.setModifyCountInterface(ShopCarAvtivity.this);// 關(guān)鍵步驟2,設(shè)置數(shù)量增減接口
for (int i = 0; i < goodsAdapter.getGroupCount(); i++) {
lv_refresh.expandGroup(i);// 關(guān)鍵步驟3,初始化時,將ExpandableListView以展開的方式呈現(xiàn)
}
2.項(xiàng)目中使用到的數(shù)據(jù)接口
界面當(dāng)中的復(fù)選框的接口回調(diào)
public interface CheckGoodsListener {
/**
* 組選框狀態(tài)改變觸發(fā)的事件
*
* @param groupPosition 組元素位置
* @param isChecked 組元素選中與否
*/
void checkGroup(int groupPosition, boolean isChecked);
/**
* 子選框狀態(tài)改變時觸發(fā)的事件
*
* @param groupPosition 組元素位置
* @param childPosition 子元素位置
* @param isChecked 子元素選中與否
*/
void checkChild(int groupPosition, int childPosition, boolean isChecked);
/**
* 購買
* @param groupPosition
* @param childPosition
* @param isChecked
*/
void checkGoodsBuy(ShopCarModel shopCarModel, double totalMonery, int totalCount);
}
商品增加和修改的接口
/**
* 改變數(shù)量的接口
* Created by zhuangAH on 2016-11-7.
*/
public interface ModifyCountListener {
/**
* 增加操作
*
* @param groupPosition 組元素位置
* @param childPosition 子元素位置
* @param showCountView 用于展示變化后數(shù)量的View
* @param isChecked 子元素選中與否
*/
void doIncrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);
/**
* 刪減操作
*
* @param groupPosition 組元素位置
* @param childPosition 子元素位置
* @param showCountView 用于展示變化后數(shù)量的View
* @param isChecked 子元素選中與否
*/
void doDecrease(int groupPosition, int childPosition, View showCountView, boolean isChecked);
/**
* 刪除子item
*
* @param groupPosition
* @param childPosition
*/
void childDelete(int groupPosition, int childPosition);
}
3.在Adapter中計算商品的金額數(shù)量
單個店鋪中有多個商品,所以這個店鋪的布局,包含選擇全組的按鈕,使用了接口的回調(diào) checkInterface.checkGroup(groupPosition, ((CheckBox) v).isChecked());來判斷是否選中全組,在Activity中進(jìn)行數(shù)據(jù)的便利是否選中商品之后再刷新數(shù)據(jù)。
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupViewHolder gholder = null;
if (convertView != null && !(convertView.getTag() instanceof GroupViewHolder)) {
convertView = null;
}
if (convertView == null) {
gholder = new GroupViewHolder();
convertView = View.inflate(context, R.layout.item_shopcart_group, null);
gholder.determineChekbox = (CheckBox) convertView.findViewById(R.id.determine_chekbox);
gholder.tvSourceName = (TextView) convertView.findViewById(R.id.tv_source_name);
convertView.setTag(gholder);
} else {
gholder = (GroupViewHolder) convertView.getTag();
}
final ShopCarModel group = (ShopCarModel) getGroup(groupPosition);
gholder.tvSourceName.setText(group.getFactoryName());
gholder.determineChekbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
group.setChoosed(((CheckBox) v).isChecked());
checkInterface.checkGroup(groupPosition, ((CheckBox) v).isChecked());
}
});
gholder.determineChekbox.setChecked(group.isChoosed());
return convertView;
}
在Activity中計算便利數(shù)據(jù)
/***
* 校對組元素
*
* @param groupPosition 組元素位置
* @param isChecked 組元素選中與否
*/
@Override
public void checkGroup(int groupPosition, boolean isChecked) {
List<GoodsModel> goodsModelList = shopCarModelList.get(groupPosition).getGoodsModel();
for (int i = 0; i < goodsModelList.size(); i++) {
goodsModelList.get(i).setChoosed(isChecked);
}
goodsAdapter.notifyDataSetChanged();
}
在商品中計算數(shù)據(jù)結(jié)果:
@Override
public View getChildView(final int groupPosition, final int childPosition, final boolean isLastChild, View convertView, final ViewGroup parent) {
GoodsViewHolder goodsViewHolder = null;
int totalCount = 0;
double totalPrice = 0.00;
if (convertView != null && !(convertView.getTag() instanceof GoodsViewHolder)) {
convertView = null;
}
if (convertView == null) {
goodsViewHolder = new GoodsViewHolder();
convertView = View.inflate(context, R.layout.item_shopcart_product, null);
goodsViewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.check_box);
goodsViewHolder.ivAdapterListPic = (ImageView) convertView.findViewById(R.id.iv_adapter_list_pic);
goodsViewHolder.tvIntro = (TextView) convertView.findViewById(R.id.tv_intro);
goodsViewHolder.tvPrice = (TextView) convertView.findViewById(R.id.tv_price);
goodsViewHolder.tvBuyNum = (TextView) convertView.findViewById(R.id.tv_buy_num);
goodsViewHolder.rlNoEdtor = (RelativeLayout) convertView.findViewById(R.id.rl_no_edtor);
goodsViewHolder.tvReduce = (TextView) convertView.findViewById(R.id.tv_reduce);
goodsViewHolder.tvNum = (TextView) convertView.findViewById(R.id.tv_num);
goodsViewHolder.tvAdd = (TextView) convertView.findViewById(R.id.tv_add);
goodsViewHolder.llChangeNum = (LinearLayout) convertView.findViewById(R.id.ll_change_num);
goodsViewHolder.layout_item_foot = (LinearLayout) convertView.findViewById(R.id.layout_item_foot);
goodsViewHolder.tv_goods_number = (TextView) convertView.findViewById(R.id.tv_goods_number);
goodsViewHolder.tv_goods_menoy = (TextView) convertView.findViewById(R.id.tv_goods_menoy);
goodsViewHolder.tv_buys = (TextView) convertView.findViewById(R.id.tv_buys);
goodsViewHolder.laytou_car = (LinearLayout) convertView.findViewById(R.id.laytou_car);
convertView.setTag(goodsViewHolder);
} else {
goodsViewHolder = (GoodsViewHolder) convertView.getTag();
}
//進(jìn)行數(shù)據(jù)操作
final GoodsModel goodsInfo = (GoodsModel) getChild(groupPosition, childPosition);
if (goodsInfo != null) {
//數(shù)量初始化為0,金額初始化為0
goodsViewHolder.tv_goods_number.setText(TypeUtils.toString(0));
goodsViewHolder.tv_goods_menoy.setText("¥ " + NumberUtils.formatMoneyScale(0.00));
List<GoodsModel> goodsModel = CarUtrils.getGoodsList(goodShop, groupPosition);
//判斷是否最后一個
if ((goodsModel.size() - 1) == childPosition) {
goodsViewHolder.layout_item_foot.setVisibility(View.VISIBLE);
/**
* 統(tǒng)計操作<br>
* 1.先清空全局計數(shù)器<br>
* 2.遍歷所有子元素,只要是被選中狀態(tài)的,就進(jìn)行相關(guān)的計算操作<br>
* 3.給底部的textView進(jìn)行數(shù)據(jù)填充
*/
//1判斷商品是否選中,再進(jìn)行計算
for (int j = 0; j < goodsModel.size(); j++) {
GoodsModel model = goodsModel.get(j);
if (model.isChoosed()) {
totalCount += model.getSelectQty();
totalPrice += TypeUtils.toDouble(NumberUtils.multiply(TypeUtils.toBigDecimal(NumberUtils.formatRounded(model.getPrice())), NumberUtils.toBigDecimal(model.getSelectQty())));
}
}
if (totalPrice != 0.00) {
goodsViewHolder.tv_goods_number.setText(TypeUtils.toString(totalCount));
goodsViewHolder.tv_goods_menoy.setText(NumberUtils.formatRounded(TypeUtils.toBigDecimal(totalPrice)));
goodsViewHolder.tv_buys.setBackgroundColor(context.getResources().getColor(R.color.main_color));
goodsViewHolder.tv_buys.setEnabled(true);
} else {
goodsViewHolder.tv_goods_number.setText(TypeUtils.toString(0));
goodsViewHolder.tv_goods_menoy.setText("¥ " + NumberUtils.formatMoneyScale(0.00));
goodsViewHolder.tv_buys.setBackgroundColor(context.getResources().getColor(R.color.resport_line));
goodsViewHolder.tv_buys.setEnabled(false);
}
} else {
goodsViewHolder.layout_item_foot.setVisibility(View.GONE);
}
//設(shè)置基礎(chǔ)數(shù)據(jù)
if (goodsInfo.getImageSrc() != null) {
Glide.with(context)
.load(goodsInfo.getImageSrc())
.centerCrop()
.placeholder(R.mipmap.test2)
.crossFade()
.into(goodsViewHolder.ivAdapterListPic);
}
goodsViewHolder.tvIntro.setText(goodsInfo.getName());
goodsViewHolder.tvPrice.setText("¥ " + NumberUtils.formatRounded(goodsInfo.getPrice()));
goodsViewHolder.tvBuyNum.setText("X " + NumberUtils.formatQty(goodsInfo.getQty()));
//set Goods Check
goodsViewHolder.checkBox.setChecked(goodsInfo.isChoosed());
goodsViewHolder.tvNum.setText(TypeUtils.toString(goodsInfo.getSelectQty()));
//選中的狀態(tài)下才能觸發(fā)點(diǎn)擊事件
goodsViewHolder.tvAdd.setEnabled(true);
goodsViewHolder.tvReduce.setEnabled(true);
//加減
final GoodsViewHolder finalGoodsViewHolder = goodsViewHolder;
goodsViewHolder.tvAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
modifyCountInterface.doIncrease(groupPosition, childPosition, finalGoodsViewHolder.tvNum, finalGoodsViewHolder.checkBox.isChecked());// 暴露增加接口
}
});
final GoodsViewHolder finalGoodsViewHolder1 = goodsViewHolder;
goodsViewHolder.tvReduce.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
modifyCountInterface.doDecrease(groupPosition, childPosition, finalGoodsViewHolder1.tvNum, finalGoodsViewHolder1.checkBox.isChecked());// 暴露刪減接口
}
});
//goods check state OnClick
goodsViewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
goodsInfo.setChoosed(((CheckBox) v).isChecked());
((CheckBox) v).setChecked(((CheckBox) v).isChecked());
checkInterface.checkChild(groupPosition, childPosition, ((CheckBox) v).isChecked());
}
});
//onClick to OrderDetailActivity
final double finalTotalPrice = totalPrice;
final int finalTotalCount = totalCount;
goodsViewHolder.tv_buys.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//check goods is not null
//if not null can go other activity
ShopCarModel shopCar = CarUtrils.getCheckShopCar(goodShop, groupPosition);
if (shopCar != null && shopCar.getGoodsModel().size() > 0) {
checkInterface.checkGoodsBuy(shopCar, finalTotalPrice, finalTotalCount);
}
}
});
}
goodsViewHolder.laytou_car.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UIHelper.toShopCarGoodsDetailActivity(context, goodsInfo);
}
});
return convertView;
}
以上代碼的是先判斷當(dāng)前組是否為一個店鋪中的最后一個,在最后一個元素中局部計算當(dāng)前的Group的數(shù)據(jù),根據(jù)數(shù)據(jù)來選擇是否復(fù)位數(shù)據(jù)展示以及顯示,把計算的數(shù)據(jù)展示出來,最后通過接口回調(diào)的方式跳轉(zhuǎn)界面,把數(shù)據(jù)傳到Activity中去。就這樣子就處理完這個購物車的邏輯,以上可能不符合你的邏輯,但是你可以稍微修改就拿來使用。
Github地址: https://github.com/anhuifix/singleShopCar/tree/master
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android仿餓了么加入購物車旋轉(zhuǎn)控件自帶閃轉(zhuǎn)騰挪動畫的按鈕效果(實(shí)例詳解)
- Android把商品添加到購物車的動畫效果(貝塞爾曲線)
- Android貝塞爾曲線初步學(xué)習(xí)第三課 Android實(shí)現(xiàn)添加至購物車的運(yùn)動軌跡
- Android中實(shí)現(xiàn)淘寶購物車RecyclerView或LIstView的嵌套選擇的邏輯
- Android制作簡單的普通購物車
- Android實(shí)現(xiàn)仿淘寶購物車增加和減少商品數(shù)量功能demo示例
- Android實(shí)現(xiàn)的仿淘寶購物車demo示例
- Android仿外賣購物車功能
- Android實(shí)現(xiàn)購物車功能
- Android實(shí)現(xiàn)購物車添加物品的動畫效果
相關(guān)文章
基于Android自定義控件實(shí)現(xiàn)刮刮樂效果
這篇文章主要介紹了基于Android自定義控件實(shí)現(xiàn)刮刮樂效果 的相關(guān)資料,需要的朋友可以參考下2015-12-12
Android Compose學(xué)習(xí)之繪制速度表盤
這篇文章主要為大家詳細(xì)介紹了Android Compose繪制速度表盤的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下2023-11-11
基于Android實(shí)現(xiàn)隨手指移動的ImageView
這篇文章主要介紹了基于Android實(shí)現(xiàn)隨手指移動的ImageView的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android如何獲取子View的位置及坐標(biāo)詳解
這篇文章主要給大家介紹了關(guān)于Android如何獲取子View的位置及坐標(biāo)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Android JNI 調(diào)用時緩存字段和方法ID示例
這篇文章主要介紹了Android JNI 調(diào)用時緩存字段和方法ID示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Flutter學(xué)習(xí)教程之Route跳轉(zhuǎn)以及數(shù)據(jù)傳遞
這篇文章主要給大家介紹了關(guān)于Flutter學(xué)習(xí)教程之Route跳轉(zhuǎn)以及數(shù)據(jù)傳遞的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08

