商城項(xiàng)目實(shí)戰(zhàn) | 17.1 輕松實(shí)現(xiàn)商品列表 list 和 grid 模式切換

本文為菜鳥窩作者劉婷的連載。”商城項(xiàng)目實(shí)戰(zhàn)”系列來聊聊仿”京東淘寶的購物商城”如何實(shí)現(xiàn)。

這篇文章是接著上篇文章《商城項(xiàng)目實(shí)戰(zhàn) | 16.1 TabLayout 實(shí)現(xiàn)商品排序功能》的,本文將著重介紹如何輕松商品列表 list 和 grid 模式切換,先看實(shí)現(xiàn)效果吧。

實(shí)現(xiàn)效果
實(shí)現(xiàn)效果

大家一定很奇怪,為什么商品列表 list 和 grid 模式切換要特別寫一篇文章來講呢?因?yàn)樾【幬矣龅娇恿耍恢揽吹奖疚牡母魑皇欠裼型瑯拥慕?jīng)歷啊,下面就詳細(xì)說說怎么回事吧。

RecyclerView 的 notify 的坑

RecyclerView 是 ListView 和 GridView 的新的列表控件,意在代替 ListView 和 GridView,它有很多的優(yōu)點(diǎn),不必小編我來多說了,誰用誰知道啊,但是小編在使用 RecyclerView 的自帶的 notifyItemRangeChanged(int positionStart, int itemCount) 和 notifyDataSetChanged() 想要來實(shí)現(xiàn)商品列表 list 和 grid 模式切換時(shí),卻不小心掉坑里了。

下面是我最開始實(shí)現(xiàn)商品列表 list 和 grid 模式切換的過程。

1. 設(shè)置list 和 grid 兩種模式

既然需要切換兩種模式,自然需要標(biāo)志來標(biāo)識(shí)兩種模式。

public static final int ACTION_LIST=1;
public static final int ACTION_GIRD=2;

ACTION_LIST 是 list 列表模式,ACTION_GIRD 是 grid 模式。

2. Adapter 中添加刷新布局的方法

在商品列表的 Adapter 中添加布局刷新的方法,為之后的模式切換時(shí)調(diào)用。

public void  resetLayout(int layoutId){

        this.layoutResId  = layoutId;

        notifyItemRangeChanged(0,getDatas().size());

    }

layoutResId 為 item 項(xiàng)的布局 id,getDatas() 方法是用來獲取列表所有的數(shù)據(jù) list 的,簡(jiǎn)單來看,這個(gè)方法的作用就是重置布局 id,也就是重置布局,然后調(diào)用 notifyItemRangeChanged(int positionStart, int itemCount) 方法來刷新布局。

3. 添加模式切換方法

private void changeMode(View v){
       int action = (int) v.getTag();

        if(ACTION_LIST == action){

            mToolbar.setRightButtonIcon(R.drawable.icon_list_32);
            mToolbar.getRightButton().setTag(ACTION_GIRD);

            mWaresAdapter.resetLayout(R.layout.template_grid_wares);


           mRecyclerview_wares.setLayoutManager(new GridLayoutManager(this,2));

        }
        else if(ACTION_GIRD == action){


            mToolbar.setRightButtonIcon(R.drawable.icon_grid_32);
            mToolbar.getRightButton().setTag(ACTION_LIST);

            mWaresAdapter.resetLayout(R.layout.template_hot_wares);

            mRecyclerview_wares.setLayoutManager(new LinearLayoutManager(this));
        }
}

上面的代碼也很好理解,根據(jù)當(dāng)前的模式進(jìn)行切換操作,比如說當(dāng)前是 list 模式,則要修改 Toolbar 上面的圖標(biāo)為 list 的圖標(biāo),然后修改當(dāng)前模式為 ACTION_GIRD,調(diào)用前面在 Adapter 中寫好的刷新布局的方法 resetLayout(int layoutId),并且設(shè)置列表的 LayoutManager 為網(wǎng)格,也就是列表為網(wǎng)格模式,而當(dāng)前是 grid 模式時(shí)同理。

4. 效果圖

運(yùn)行代碼,獲取效果圖,初始的 list 模式?jīng)]有任何的問題,但是隨后進(jìn)行 grid 網(wǎng)格模式切換時(shí)就出錯(cuò)了,效果如下。

error
error

這是在模擬器上面運(yùn)行的情況,使用 notifyItemRangeChanged(int positionStart, int itemCount) 刷新布局看來是不行啊,隨后改用 notifyDataSetChanged() 方法來刷新,發(fā)現(xiàn)還是這樣,于是再多次嘗試之后,選擇了重置 Adapter。

輕松實(shí)現(xiàn)商品列表 list 和 grid 模式切換

在上面的方法失敗后,我改用了其他的辦法,最終選擇了重置 Adapter,那就是每次都要重新 new 一下 Adapter,這個(gè)辦法雖然不是很完美,但是實(shí)現(xiàn)的效果不錯(cuò),如果有更好的方法的話,歡迎一起討論。

1. 重置 Adapter

使用 RecyclerView 自帶的 notifyItemRangeChanged(int positionStart, int itemCount) 刷新方法雖然簡(jiǎn)單,但是在實(shí)際的使用過程中在數(shù)據(jù)量較大時(shí)一般都會(huì)使用 View 重用來解決滑動(dòng)卡頓的問題,所以即使刷新了,也還是會(huì)存在所謂的 View 緩沖,所以最好是重新 new 一下 Adapter 吧。

private void resetAdapter(List datas) {
        if (ACTION_GIRD == (int) toolbar.getRightButton().getTag()) {
            mWaresAdapter = new HWAdapter(this, datas, R.layout.grid_item_wares_layout);
            recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
        } else if (ACTION_LIST == (int) toolbar.getRightButton().getTag()) {
            mWaresAdapter = new HWAdapter(this, datas, R.layout.recycler_item_wares_layout);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));

            recyclerView.setItemAnimator(new DefaultItemAnimator());
        }

        if(mWaresAdapter == null){
            recyclerView.addItemDecoration(new WareItemDecoration(this, WareItemDecoration.VERTICAL_LIST));
        }
        recyclerView.setAdapter(mWaresAdapter);
    }

根據(jù)目前的模式狀態(tài),重新 new 適配器,同時(shí)重置布局和設(shè)置 RecyclerView 的布局排列方式。

2. 修改模式切換方法

修改之前的模式切換方法,在點(diǎn)擊圖標(biāo)時(shí),調(diào)用 resetAdapter(List datas) 來重置適配器。 Adapter。

private void changeMode(View v){
int action = (int) view.getTag();

        if (ACTION_LIST == action) {//列表模式下

            toolbar.setRightButtonIcon(R.mipmap.ic_list);
            toolbar.getRightButton().setTag(ACTION_GIRD);
            pager.refresh();
            recyclerView.scrollToPosition(0);

        } else if (ACTION_GIRD == action) {//網(wǎng)格模式下

            toolbar.setRightButtonIcon(R.mipmap.ic_grid);
            toolbar.getRightButton().setTag(ACTION_LIST);
            pager.refresh();
            recyclerView.scrollToPosition(0);
        }
}

根據(jù)不同的模式下,對(duì)商品列表進(jìn)行 list 模式和 grid 模式的切換。

3. 效果圖

修改代碼之后,運(yùn)行效果得到如下圖所示。

實(shí)現(xiàn)效果
實(shí)現(xiàn)效果

搗鼓了一下,最終還是實(shí)現(xiàn)了商品列表 list 和 grid 模式切換,個(gè)人建議,Adapter 的 notify 方法還是需要一些完善的,所以在實(shí)際開發(fā)中還是盡量少通過這種來對(duì)布局刷新,對(duì)于實(shí)現(xiàn)商品列表 list 和 grid 模式切換,如果有更好的方法的話,請(qǐng)指教。

擼這個(gè)項(xiàng)目的一半,你就是大神 , 戳http://mp.weixin.qq.com/s/ZagocTlDfxZpC2IjUSFhHg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,552評(píng)論 25 708
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,814評(píng)論 1 92
  • “人生沒有真正的喜歡和不喜歡,最直接的喜歡就是吃喝玩樂”。這是很久之前我媽教訓(xùn)我的話。最近因?yàn)楣ぷ骱蜕钌系囊恍┈?..
    蔣小花兒閱讀 687評(píng)論 0 0
  • 昨天晚上,我做夢(mèng)了,突然之間夢(mèng)到了奶奶,那個(gè)和藹的,可親的,倔強(qiáng)的,卻又永遠(yuǎn)都那么的低眉順眼的服侍那一幫幫人的老婦...
    李星凝閱讀 590評(píng)論 1 4