本文為菜鳥窩作者劉婷的連載?!鄙坛琼?xiàng)目實(shí)戰(zhàn)”系列來聊聊仿”京東淘寶的購物商城”如何實(shí)現(xiàn)。
在上一篇文章《商城項(xiàng)目實(shí)戰(zhàn) | 14.1 仿京東購物車的實(shí)現(xiàn)(一)》中已經(jīng)實(shí)現(xiàn)了購物車模塊商品列表的顯示,那么下面我們要實(shí)現(xiàn)的就是購物車中商品的選擇、商品合計(jì)以及商品的編輯模式和完成模式的切換,效果圖還是要先看看。

這是編輯模式的時(shí)候的界面,對比之前的完成模式下的界面,首先上面的“編輯”文字變成了“完成”,其次下面的“去結(jié)算”按鈕變?yōu)榱恕皠h除”按鈕了,也沒有合計(jì)。不過模式的切換是最后一步,先來實(shí)現(xiàn)商品的選擇效果吧。
實(shí)現(xiàn)購物車商品選中效果
購物車的商品選中有幾個(gè)要點(diǎn),第一每項(xiàng)商品 item 中都有一個(gè) checkbox,而最底部還有一個(gè)全選的 checkbox,當(dāng)所有的商品都選中時(shí),全選按鈕要處于選中狀態(tài),而當(dāng)商品列表中有一個(gè)商品未選中時(shí),全選按鈕處于未選中狀態(tài),第二就是當(dāng)全選按鈕選中時(shí),所有商品都要選中,當(dāng)全選按鈕不被選中時(shí),所有商品都要取消選中。這么一大段話,理解起來可能不太容易,但是實(shí)現(xiàn)并不復(fù)雜。
1.實(shí)現(xiàn)商品項(xiàng)選中判斷是否全選
首先來實(shí)現(xiàn)上文所說的第一種情況,通過商品列表 item 項(xiàng)的選中情況來判斷全選按鈕是否要選中,這里的實(shí)現(xiàn)都是在列表的 Adapter, CartAdapter 中實(shí)現(xiàn)的。
private void checkListen() {
int count = 0;
int checkNum = 0;
if (datas != null) {
count = datas.size();
for (ShoppingCartInfo cart : datas) {
if (!cart.isChecked()) {
checkBox.setChecked(false);
break;
} else {
checkNum = checkNum + 1;
}
}
if (count == checkNum) {
checkBox.setChecked(true);
}
}
}
checkbox 就是全選按鈕,根據(jù)選中的商品數(shù)量是否等于總的商品數(shù),如果等于的話,就要全選,不等于則是不全選,也就是全選按鈕處于未選中狀態(tài)。
2.實(shí)現(xiàn)全選判斷商品是否要被選中
因?yàn)檫@里的全選按鈕直接點(diǎn)擊下就要使得選中按鈕處于選中狀態(tài)或者是未選中狀態(tài),所以就直接為 checkbox 全選按鈕添加點(diǎn)擊事件的監(jiān)聽。
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAll_None(checkBox.isChecked());
}
});
public void checkAll_None(boolean isChecked){
if(!isNull())
return ;
int i=0;
for (ShoppingCartInfo cart :datas){
cart.setIsChecked(isChecked);
notifyItemChanged(i);
i++;
}
}
checkAll_None(boolean isChecked) 根據(jù) checkbox 全選按鈕的狀態(tài)來遍歷所有的商品項(xiàng),設(shè)置所有的商品項(xiàng)處于選中或未選中的狀態(tài)。
實(shí)現(xiàn)商品合計(jì)
商品的合計(jì)是指對商品總價(jià)的計(jì)算,這要根據(jù)選中的不同商品的價(jià)格乘以數(shù)量來取得,所以這里也需要根據(jù)商品項(xiàng)的是否選中狀態(tài),商品的合計(jì)也可以放在 CartAdapter 中實(shí)現(xiàn),和上文的商品選中效果一起處理。
public void showTotalPrice(){
float total = getTotalPrice();
textView.setText(Html.fromHtml("合計(jì) ¥<span style='color:#eb4f38'>" + total + "</span>"), TextView.BufferType.SPANNABLE);
}
private float getTotalPrice(){
float sum=0;
if(!isNull())
return sum;
for (ShoppingCartInfo cart:
datas) {
if(cart.isChecked())
sum += cart.getCount()*cart.getPrice();
}
return sum;
}
getTotalPrice() 方法是根據(jù)商品項(xiàng)中所選中商品的數(shù)量乘以價(jià)格來計(jì)算獲得總價(jià),然后在 showTotalPrice() 中調(diào)用 getTotalPrice() 直接取得總價(jià),最后顯示在合計(jì)的 TextView 上。
實(shí)現(xiàn)編輯模式和完成模式的切換
購物車模塊中有編輯模式和完成模式兩種,編輯模式的時(shí)候可以對商品進(jìn)行刪除,而在完成模式時(shí)就可以去結(jié)算了,完成模式已經(jīng)基本實(shí)現(xiàn)了,下面來主要實(shí)現(xiàn)編輯模式以及兩種模式之間的切換。
1.實(shí)現(xiàn)編輯模式
編輯模式的時(shí)候有個(gè)刪除按鈕,簡單起見,就直接在之前定義好的布局文件中添加一個(gè)刪除的按鈕。
<Button
android:id="@+id/cart_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="40dp"
android:minWidth="80dp"
android:text="@string/delete"
style="@style/bigRedButton"/>
刪除按鈕寫好了,下面就是刪除商品的操作了,為刪除按鈕添加監(jiān)聽事件。
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
delCart();
}
});
public void delCart(){
if(!isNull())
return ;
for(Iterator iterator = datas.iterator(); iterator.hasNext();){
ShoppingCartInfo cart = (ShoppingCartInfo) iterator.next();
if(cart.isChecked()){
int position = datas.indexOf(cart);
cartProvider.delete(cart);
iterator.remove();
notifyItemRemoved(position);
}
}
}
判斷商品項(xiàng)是否被選中,如果被選中了,就要進(jìn)行移除的操作,也就是刪除了。
2.實(shí)現(xiàn)編輯模式和完成模式的切換
2.1 添加區(qū)分標(biāo)志
模式的切換,自然要有一個(gè)標(biāo)志來區(qū)分是編輯模式,還是完成模式,這里定義兩個(gè) int 類型的標(biāo)志。
public static final int ACTION_EDIT=1;
public static final int ACTION_CAMPLATE=2;
ACTION_EDIT 表示編輯模式,ACTION_CAMPLATE 表示的則是完成模式。
2.2 添加事件監(jiān)聽
無論是編輯模式還是完成模式的顯示,這些都要在頂部的右側(cè)按鈕點(diǎn)擊時(shí)觸發(fā),所以為右側(cè)按鈕添加監(jiān)聽事件。
btnEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int action = (int) v.getTag();
if(ACTION_EDIT == action){
//切換完成模式
}
else if(ACTION_CAMPLATE == action){
//切換編輯模式
}
}
});
右側(cè)按鈕的點(diǎn)擊事件監(jiān)聽要根據(jù)當(dāng)前的模式來區(qū)分,如果是編輯模式,則要進(jìn)入完成模式,如果是完成模式則要進(jìn)入編輯模式。
2.3 切換為編輯模式
界面的初始狀態(tài)是完成模式,所以在初始化的時(shí)候不要忘記了設(shè)置初始為完成模式。
btnEdit.setTag(ACTION_CAMPLATE);
這時(shí)候點(diǎn)擊右側(cè)按鈕就要進(jìn)入到編輯模式中,先來實(shí)現(xiàn)完成模式的切換。
private void showDelControl(){
mToolbar.getRightButton().setText("完成");
mTextTotal.setVisibility(View.GONE);
mBtnOrder.setVisibility(View.GONE);
mBtnDel.setVisibility(View.VISIBLE);
mToolbar.getRightButton().setTag(ACTION_EDIT);
mAdapter.checkAll_None(false);
mCheckBox.setChecked(false);
}
切換為完成模式,右側(cè)按鈕文本為“完成”,合計(jì)和結(jié)算要隱藏,刪除按鈕要顯示,修改目前的模式為編輯模式,同時(shí)不要選中任意商品,并且全選也不能被選中。
2.4 切換為完成模式
切換到完成模式的處理和切換到編輯模式的處理類似,也是寫在一個(gè)方法里面,不過是 hideDelControl() 方法。
private void hideDelControl(){
mTextTotal.setVisibility(View.VISIBLE);
mBtnOrder.setVisibility(View.VISIBLE);
mBtnDel.setVisibility(View.GONE);
mToolbar.setRightButtonText("編輯");
mToolbar.getRightButton().setTag(ACTION_CAMPLATE);
mAdapter.checkAll_None(true);
mAdapter.showTotalPrice();
mCheckBox.setChecked(true);
}
切換為編輯模式,右側(cè)按鈕文本為“編輯”,合計(jì)和結(jié)算要顯示,刪除按鈕要隱藏,修改目前的模式為完成模式,所有商品都要被選中。
效果圖
運(yùn)行最終代碼獲取到效果圖。

到這里,仿京東購物車模塊的基本功能就都已經(jīng)實(shí)現(xiàn)了。
擼這個(gè)項(xiàng)目的一半,你就是大神 , 戳http://mp.weixin.qq.com/s/ZagocTlDfxZpC2IjUSFhHg