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
最后附上完整的Demo下载: 
http://download.csdn.net/download/a466302603/10048064
--------------------- 
作者:卡蓝_ 
来源:CSDN 
原文:https://blog.csdn.net/a466302603/article/details/78411612 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/bfboys/article/details/83688168