距離上一次寫文章已經(jīng)算是有點時間了俺孙,最近在公司比較忙,所以很難抽時間時間出來研究什么黑科技琳猫。所以梅誓,這次就想分享一下自己的項目經(jīng)驗沽讹,在外包公司里面必須遇到和學(xué)會的購物車界面和邏輯科汗。有人說購物車一般需要做3天或者5天藻烤,但我看來,第一次做只需要用兩到三個小時想好后臺回來的數(shù)據(jù)處理头滔,和處理好該有的邏輯就好了怖亭。在分析自己的做法之前先看看我做的購物車的效果。
我自己覺得拙毫,效果還不懶依许,哈哈棺禾。那接下來就分析一下我自己的理解和做法缀蹄。
如果不想聽我啰嗦的人可以直接去下載源碼源碼下載鏈接
首先我們看看后臺返回來的數(shù)據(jù)類型是怎么樣的,再決定怎么去做相應(yīng)的界面膘婶。
{
"message": "查詢成功",
"status": "200",
"result": [
{
"shopId": 2,//店鋪
"shopName": null,//店鋪名稱
"cartlist": [//購物車商品
{
"id": 2,//購物車
"shopId": 2,
"shopName": null,
"defaultPic": "111.jpg",//默認(rèn)略縮圖
"productId": 2,//商品
"productName": null,//商品名稱
"color": null,//顏色
"size": null,//尺寸
"price": null,//單價
"count": null//數(shù)量
},
{
"id": 2,//購物車
"shopId": 2,
"shopName": null,
"defaultPic": "111.jpg",//默認(rèn)略縮圖
"productId": 2,//商品
"productName": null,//商品名稱
"color": null,//顏色
"size": null,//尺寸
"price": null,//單價
"count": null//數(shù)量
}
]
},
{
"shopId": 2,//店鋪
"shopName": null,//店鋪名稱
"cartlist": [//購物車商品
{
"id": 2,//購物車
"shopId": 2,
"shopName": null,
"defaultPic": "111.jpg",//默認(rèn)略縮圖
"productId": 2,//商品
"productName": null,//商品名稱
"color": null,//顏色
"size": null,//尺寸
"price": null,//單價
"count": null//數(shù)量
},
{
"id": 2,//購物車
"shopId": 2,
"shopName": null,
"defaultPic": "111.jpg",//默認(rèn)略縮圖
"productId": 2,//商品
"productName": null,//商品名稱
"color": null,//顏色
"size": null,//尺寸
"price": null,//單價
"count": null//數(shù)量
}
]
}
]
}
看看我們的界面缺前,我們需要做到的是每間商鋪的第一個商品的頭部顯示商鋪的名字。同一間商鋪的第二個商品開始就不顯示商鋪的名字悬襟⌒坡耄看到上面的數(shù)據(jù),我們很明顯看到有兩層數(shù)據(jù)第一層是以商鋪來分的list脊岳,第二層是以每間商鋪的商品來分的list逝段。結(jié)合我們的需求和后臺返回來的數(shù)據(jù)結(jié)構(gòu),我想到了兩種方式去構(gòu)造這個界面割捅。
1.用RecyclerView嵌套RecyclerView奶躯,
商鋪是第一層RecyclerView的item,每間商鋪的商品顯示是第二層RecyclerView亿驾。
2.一層RecyclerView解決問題:
(1)分兩種布局去做嘹黔,第一種布局是含有商鋪名字header的item,
第二種是不含有商鋪名字no_header的item莫瞬。
(2)一種布局完成所有操作儡蔓,具體做法是郭蕉,記錄以同一間商鋪id的第一件商品的位置,
然后通過這樣的記錄在adapter里面去顯示和隱藏每個item相應(yīng)的header喂江。
好吧召锈,我想到的方法都在上面羅列出來了,很明顯开呐,看過我之前文章的朋友都知道我是一個很懶的人烟勋,什么都喜歡簡潔。而且基于安卓各種View的嵌套會出現(xiàn)各種各樣的問題筐付,所以我采取了第2種的(2)解決問題卵惦,也就是用一層RecyclerView來解決整個購物車的所有問題。
下面看看RecyclerView的item布局
很明顯瓦戚,每個item都含有商鋪名字的header沮尿,那下面我就要具體講講整個購物車的界面邏輯怎么去做了。
首先我們要在商品的實體類中加入三個屬性:
看到isSelect和isShopSelect兩個屬性可能大家都明白這是用來干什么的较解,唯獨isFirst這個屬性可能大家不是很懂畜疾。那下面我來解釋一下:
我們用一層的RecyclerView來做到效果圖那樣看上去有兩層嵌套的效果,必須依賴isFirst這個屬性印衔》却罚看下下面的數(shù)據(jù)類型大家就會明白:
我們拿到數(shù)據(jù)之后直接舍棄了第一層的商鋪的一些信息,然后把所有的商品信息放到同一條list里面奸焙。
ArrayList<商品> mGoPayList = new ArrayList<>()瞎暑;
mGoPayList.addall(商鋪.商品);
然后直接利用每件商品里面的Shopid來標(biāo)記一下哪件商品是在商鋪的第一個商品:
public static void isSelectFirst(List<ShopCartBean.CartlistBean> list){
if(list.size() > 0) {
//頭個商品一定屬于它所在商鋪的第一個位置与帆,isFirst標(biāo)記為1.
list.get(0).setIsFirst(1);
for (int i = 1; i < list.size(); i++) {
//每個商品跟它前一個商品比較了赌,如果Shopid相同isFirst則標(biāo)記為2,
//如果Shopid不同玄糟,isFirst標(biāo)記為1.
if (list.get(i).getShopId() == list.get(i - 1).getShopId()) {
list.get(i).setIsFirst(2);
} else {
list.get(i).setIsFirst(1);
}
}
}
}
然后我們利用這個isFirst屬性在adapter來判斷子項是否顯示它屬于哪間商鋪的header勿她。
好了,以上購物車的界面就算完成了阵翎,是不是很簡單逢并?
下面我們來講講剩下的一半,購物車的邏輯郭卫,也就是各種選中與未選中的控制砍聊。首先,讓商鋪的勾選與商鋪下的商品的勾選連上關(guān)系箱沦。
我思前想后辩恼,發(fā)現(xiàn)用一個二層for循環(huán)就可以做到這樣的效果,我利用的就是上面我讓大家去給商品加的三個屬性,isSelect灶伊、isShopSelect和isFirst疆前。
holder.ivShopCartClothSel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
data.get(position).setSelect(!data.get(position).getIsSelect());
//通過循環(huán)找出不同商鋪被標(biāo)記的第一個商品的位置
for(int i = 0;i < data.size(); i++){
if(data.get(i).getIsFirst() == 1) {
//遍歷去找出同一家商鋪的所有商品的勾選情況
for(int j = 0;j < data.size();j++){
//如果是同一家商鋪的商品,并且其中一個商品是未選中聘萨,
//那么商鋪的全選勾選取消
if(data.get(j).getShopId() == data.get(i).getShopId()
&& !data.get(j).getIsSelect()){
data.get(i).setShopSelect(false);
break;
}else{
//如果是同一家商鋪的商品竹椒,并且所有商品是選中,那么商鋪的選中全選勾選
data.get(i).setShopSelect(true);
}
}
}
}
notifyDataSetChanged();
}
});
然后我們看看商鋪的勾選控制商品的勾選情況是怎么做到的:
holder.ivShopCartShopSel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//如果position的isFirst為1米辐,證明是每個商鋪的第一件商品
//而且這件商品有商鋪的頭部header
if(data.get(position).getIsFirst() == 1) {
//isShopSelect取反選 data.get(position).setShopSelect(!data.get(position).getIsShopSelect());
for(int i = 0;i < data.size();i++){
//如果Shopid與position的Shopid相同胸完,
// 則設(shè)置它的選中情況與position的isShopSelect選中情況一樣
if(data.get(i).getShopId() == data.get(position).getShopId()){
data.get(i).setSelect(data.get(position).getIsShopSelect());
}
}
notifyDataSetChanged();
}
}
});
用一個二層的for循環(huán)處理好數(shù)據(jù),只需要按屬性來判斷顯示選中情況就好了
如果還想讓外層與RecyclerView的子項互相控制的話像這樣:
很簡單翘贮,我們只需要像RecyclerView的子項監(jiān)聽一樣赊窥,寫個接口,就可以很容易與Activity的其他控件互相控制
好了狸页,以上就是我自己做的一個購物車锨能,看上去很復(fù)雜,其實用很簡單的原理就可以實現(xiàn)芍耘,只需要三個屬性isSelect址遇、isShopSelect和isFirst,一層RecyclerView和一個二層for循環(huán)完美實現(xiàn)整個購物車的所有功能,無需嵌套布局斋竞。有興趣的同學(xué)可以下載源碼下來慢慢研究琢磨倔约,一起進(jìn)步!
源碼下載鏈接