Android:玩轉(zhuǎn)購物車界面和邏輯只需要一層Recyclerview署穗,一個二層for循環(huán)和三個屬性

距離上一次寫文章已經(jīng)算是有點時間了俺孙,最近在公司比較忙,所以很難抽時間時間出來研究什么黑科技琳猫。所以梅誓,這次就想分享一下自己的項目經(jīng)驗沽讹,在外包公司里面必須遇到和學(xué)會的購物車界面和邏輯科汗。有人說購物車一般需要做3天或者5天藻烤,但我看來,第一次做只需要用兩到三個小時想好后臺回來的數(shù)據(jù)處理头滔,和處理好該有的邏輯就好了怖亭。在分析自己的做法之前先看看我做的購物車的效果。

購物車效果圖.gif

我自己覺得拙毫,效果還不懶依许,哈哈棺禾。那接下來就分析一下我自己的理解和做法缀蹄。
如果不想聽我啰嗦的人可以直接去下載源碼源碼下載鏈接
首先我們看看后臺返回來的數(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的布局.png

很明顯瓦戚,每個item都含有商鋪名字的header沮尿,那下面我就要具體講講整個購物車的界面邏輯怎么去做了。
首先我們要在商品的實體類中加入三個屬性:


添加三個關(guān)鍵屬性.png

看到isSelect和isShopSelect兩個屬性可能大家都明白這是用來干什么的较解,唯獨isFirst這個屬性可能大家不是很懂畜疾。那下面我來解釋一下:
我們用一層的RecyclerView來做到效果圖那樣看上去有兩層嵌套的效果,必須依賴isFirst這個屬性印衔》却罚看下下面的數(shù)據(jù)類型大家就會明白:
數(shù)據(jù)類型.png

我們拿到數(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勿她。

3(I[72}K2W70Z]6@64BV`YG.png

是否顯示頭部商鋪名.png
界面效果圖.png

好了,以上購物車的界面就算完成了阵翎,是不是很簡單逢并?
下面我們來講講剩下的一半,購物車的邏輯郭卫,也就是各種選中與未選中的控制砍聊。首先,讓商鋪的勾選與商鋪下的商品的勾選連上關(guān)系箱沦。

用商鋪的勾選跟商品的勾選連上關(guān)系.png

我思前想后辩恼,發(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ù),只需要按屬性來判斷顯示選中情況就好了


根據(jù)屬性顯示該商品或商鋪的選中情況.png

如果還想讓外層與RecyclerView的子項互相控制的話像這樣:


外層與RecyclerView的子項互相控制.png

很簡單翘贮,我們只需要像RecyclerView的子項監(jiān)聽一樣赊窥,寫個接口,就可以很容易與Activity的其他控件互相控制
實時更新的接口.png
adapter的方法.png

Activity需要怎么寫.png

好了狸页,以上就是我自己做的一個購物車锨能,看上去很復(fù)雜,其實用很簡單的原理就可以實現(xiàn)芍耘,只需要三個屬性isSelect址遇、isShopSelect和isFirst,一層RecyclerView和一個二層for循環(huán)完美實現(xiàn)整個購物車的所有功能,無需嵌套布局斋竞。有興趣的同學(xué)可以下載源碼下來慢慢研究琢磨倔约,一起進(jìn)步!
源碼下載鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坝初,一起剝皮案震驚了整個濱河市浸剩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脖卖,老刑警劉巖乒省,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畦木,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來常遂,“玉大人,你說我怎么就攤上這事。” “怎么了砚作?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上蓉驹,老公的妹妹穿的比我還像新娘狠持。我一直安慰自己,他們只是感情好瞻润,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布喘垂。 她就那樣靜靜地躺著,像睡著了一般绍撞。 火紅的嫁衣襯著肌膚如雪正勒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天傻铣,我揣著相機與錄音章贞,去河邊找鬼。 笑死非洲,一個胖子當(dāng)著我的面吹牛鸭限,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播两踏,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼败京,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梦染?” 一聲冷哼從身側(cè)響起赡麦,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弓坞,沒想到半個月后隧甚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體车荔,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡渡冻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忧便。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片族吻。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡帽借,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出超歌,到底是詐尸還是另有隱情砍艾,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布巍举,位于F島的核電站脆荷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏懊悯。R本人自食惡果不足惜蜓谋,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炭分。 院中可真熱鬧桃焕,春花似錦、人聲如沸捧毛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呀忧。三九已至师痕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間而账,已是汗流浹背七兜。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留福扬,地道東北人腕铸。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像铛碑,于是被迫代替她去往敵國和親狠裹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容