1. 程式人生 > >RecyclerView載入多型別item 實現淘寶首頁佈局

RecyclerView載入多型別item 實現淘寶首頁佈局

主要為大家介紹如何用RecycleView來實現淘寶首頁複雜的佈局,做電商類app的小夥伴們可以略作參考。

首先上效果圖:

下面說一下實現方式,主要思路就是根據不同的資料型別去制定不同的item型別,然後動態地去設定這些item的寬高,設定item的型別相信大家都會,我這裡就不做闡述了,主要是說一下給不同型別的item設定不同的寬度。

首先,我們給RecyclerView設定一個列數為x的GridLayoutManager,然後再動態地為不同型別的item分別設定SpanSize。比如GridLayoutManager列數為4,item的SpanSize也為4,那麼這個item的寬度就是RecyclerView寬度的100%,最終的效果就跟列表一樣。同理,item的SpanSize如果是2,那麼就佔一行的一半寬度,item的SpanSize是1,佔1/4寬度…

比如我在demo裡面是把列數設為12:

HomeAdapter adapter = new HomeAdapter(this);
GridLayoutManager layoutManger = new GridLayoutManager(this, 12);
rcHome.setLayoutManager(layoutManger);
rcHome.setAdapter(adapter);
  • 1
  • 2
  • 3
  • 4

然後在adapter裡面重寫onAttachedToRecyclerView方法,為不同的ItemViewType設定不同的SpanSize:

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    switch (type) {
                        case BANNER:
                            return 12;
                        case COLUMN:
                            return 3;
                        case MARQUEE:
                            return 12;
                        case NUM_TWO:
                            return 6;
                        case TITLE:
                            return 12;
                        case NUM_THREE:
                            return 4;
                        case NORMAL:
                            return 6;
                        default:
                            return 12;
                    }
                }
            });
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

12代表寬度佔滿全屏,3代表佔螢幕的1/4,6代表佔螢幕的1/2等等,最終就可以實現上圖中的效果。

程式碼不多,就直接貼在下面了:

MainActivity

public class MainActivity extends AppCompatActivity {
    private Unbinder mUnBinder;
    @BindView(R.id.rc_home)
    RecyclerView rcHome;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUnBinder = ButterKnife.bind(this);
        initView();
    }

    private void initView() {
        HomeAdapter adapter = new HomeAdapter(this);
        GridLayoutManager layoutManger = new GridLayoutManager(this, 12);
        rcHome.setLayoutManager(layoutManger);
        rcHome.setAdapter(adapter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mUnBinder.unbind();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

HomeAdapter

public class HomeAdapter extends RecyclerView.Adapter {
    private LayoutInflater inflater;
    private List<Integer> imgList;
    private List<String> marqueeList;

    private static final int BANNER = 0;
    private static final int COLUMN = 1;
    private static final int MARQUEE = 2;
    private static final int NUM_TWO = 3;
    private static final int TITLE = 4;
    private static final int NUM_THREE = 5;
    private static final int NORMAL = 6;

    public HomeAdapter(Context mContext) {
        inflater = LayoutInflater.from(mContext);
        //新增輪播資料
        addBannerData();
        //新增跑馬燈資料
        addMarqueeData();
    }

    @Override
    public int getItemCount() {
        return 25;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return BANNER;
        } else if (position >= 1 && position <= 8) {
            return COLUMN;
        } else if (position == 9) {
            return MARQUEE;
        } else if (position >= 10 && position <= 13) {
            return NUM_TWO;
        } else if (position == 14 || position == 18) {
            return TITLE;
        } else if (position >= 15 && position <= 17) {
            return NUM_THREE;
        } else if (position >= 19 && position <= 24) {
            return NORMAL;
        }
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case BANNER:
                View itemBanner = inflater.inflate(R.layout.item_banner, parent, false);
                return new BannerHolder(itemBanner);
            case COLUMN:
                View itemColumn = inflater.inflate(R.layout.item_column, parent, false);
                return new ColumnHolder(itemColumn);
            case MARQUEE:
                View itemMarquee = inflater.inflate(R.layout.item_marquee, parent, false);
                return new MarqueeHolder(itemMarquee);
            case NUM_TWO:
                View itemNumTwo = inflater.inflate(R.layout.item_num_two, parent, false);
                return new NumTwoHolder(itemNumTwo);
            case TITLE:
                View itemTitle = inflater.inflate(R.layout.item_title, parent, false);
                return new TitleHolder(itemTitle);
            case NUM_THREE:
                View itemNumThree = inflater.inflate(R.layout.item_num_three, parent, false);
                return new NumThreeHolder(itemNumThree);
            case NORMAL:
                View itemNormal = inflater.inflate(R.layout.item_normal, parent, false);
                return new NormalHolder(itemNormal);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof BannerHolder) {
            setBanner((BannerHolder) holder);
        } else if (holder instanceof ColumnHolder) {

        } else if (holder instanceof MarqueeHolder && marqueeList != null) {
            setMarquee((MarqueeHolder) holder);
        } else if (holder instanceof NumTwoHolder) {

        } else if (holder instanceof TitleHolder) {
            setTitle((TitleHolder) holder, position);
        } else if (holder instanceof NumThreeHolder) {

        } else if (holder instanceof NormalHolder) {

        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    switch (type) {
                        case BANNER:
                            return 12;
                        case COLUMN:
                            return 3;
                        case MARQUEE:
                            return 12;
                        case NUM_TWO:
                            return 6;
                        case TITLE:
                            return 12;
                        case NUM_THREE:
                            return 4;
                        case NORMAL:
                            return 6;
                        default:
                            return 12;
                    }
                }
            });
        }
    }

    public class BannerHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.banner)
        Banner banner;

        BannerHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public class ColumnHolder extends RecyclerView.ViewHolder {

        public ColumnHolder(View itemView) {
            super(itemView);
        }
    }

    public class MarqueeHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.marquee)
        UPMarqueeView marquee;

        public MarqueeHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public class NumTwoHolder extends RecyclerView.ViewHolder {

        public NumTwoHolder(View itemView) {
            super(itemView);
        }
    }

    public class TitleHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.tv_title)
        TextView tvTitle;

        public TitleHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public class NumThreeHolder extends RecyclerView.ViewHolder {

        public NumThreeHolder(View itemView) {
            super(itemView);
        }
    }


    public class NormalHolder extends RecyclerView.ViewHolder {

        public NormalHolder(View itemView) {
            super(itemView);
        }
    }

    /**
     * 輪播圖圖片列表
     */
    private void addBannerData() {
        imgList = new ArrayList<>();
        imgList.add(R.drawable.home_pic);
        imgList.add(R.drawable.home_pic);
        imgList.add(R.drawable.home_pic);
    }

    /**
     * 新增跑馬燈資料
     */
    private void addMarqueeData() {
        marqueeList = new ArrayList<>();
        marqueeList.add("太瘋狂!IPhone X首批1分鐘賣光。");
        marqueeList.add("家人給2歲孩子喝這個,孩子智力倒退10歲!");
        marqueeList.add("自助餐裡面的潛規則,想要吃回本其實很簡單。");
        marqueeList.add("簡直是白菜價!日本玩家33萬甩賣15萬張遊戲王卡。");
    }

    /**
     * 繫結輪播圖資料
     */
    private void setBanner(BannerHolder holder) {
        holder.banner.setBannerStyle(BannerConfig.NUM_INDICATOR);
        holder.banner.setImageLoader(new GlideImageLoader());
        holder.banner.setImages(imgList);
        holder.banner.setBannerAnimation(Transformer.Default);
        holder.banner.isAutoPlay(true);
        holder.banner.setDelayTime(3000);
        holder.banner.setIndicatorGravity(BannerConfig.CENTER);
        holder.banner.start();
    }

    /**
     * 設定跑馬燈
     */
    private void setMarquee(MarqueeHolder holder) {
        List<View> views = new ArrayList<>();
        for (int i = 0; i < marqueeList.size(); i = i + 2) {
            LinearLayout view = (LinearLayout) inflater.inflate(R.layout.marquee_text, null);
            TextView textTop = (TextView) view.findViewById(R.id.text_top);
            TextView textBottom = (TextView) view.findViewById(R.id.text_bottom);
            textTop.setText(marqueeList.get(i));
            if (marqueeList.size() > i + 1) {
                textBottom.setText(marqueeList.get(i + 1));
            }
            views.add(view);
        }
        holder.marquee.setViews(views);
    }

    /**
     * 模組標題
     */
    private void setTitle(TitleHolder holder, int position) {
        switch (position) {
            case 14:
                holder.tvTitle.setText("精品推薦");
                break;
            case 18:
                holder.tvTitle.setText("猜你喜歡");
                break;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253

--------------------- 本文來自 卡藍_ 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/a466302603/article/details/78411612?utm_source=copy