RecyclerView展示多种布局
按照惯例 先看看效果图
简介
最上面是一个轮播图,然后下面是一个横向滑动的频道,然后下面就是一个GridView,再下面就是正常的布局显示了
当然这还不算是很复杂的布局,我这边只是讲讲原理和实现步骤,更多复杂布局可以根据这个去扩展
原理
给不同position的item设置不同的layout布局, 绑定不同的ViewHolder
实现步骤
1,定义不同的viewType常量(非必须)
2,在getItemViewType方法中根据position来返回不同的viewType
3,根据getItemViewType方法返回的不同的viewType在onCreateViewHolder创建不同的ViewHolder
4,onBindViewHolder方法里面用instanceof判断不同的ViewHolder来做不通的赋值处理
5,注意getItemCount的返回值
开撸代码
1,定义不同的viewType常量
上面的图片上可以看出,一共有4个type,轮播图,频道,美女,正常4个,下面是定义的常量
private final int BANNER_VIEW_TYPE = 0;//轮播图
private final int CHANNEL_VIEW_TYPE = 1;//频道
private final int GIRL_VIEW_TYPE = 2;//美女
private final int NORMAL_VIEW_TYPE = 3;//正常布局
1
2
3
4
2,在getItemViewType方法中根据position来返回不同的viewType
/**
* 获取item的类型
*
* @param position item的位置
* @return item的类型
* 有几种type就回在onCreateViewHolder方法中引入几种布局,也就是创建几个ViewHolder
*/
@Override
public int getItemViewType(int position) {
/*
区分item类型,返回不同的int类型的值
在onCreateViewHolder方法中用viewType来创建不同的ViewHolder
*/
if (position == 0) {//第0个位置是轮播图
return BANNER_VIEW_TYPE;
} else if (position == 1) {//第一个是频道布局
return CHANNEL_VIEW_TYPE;
} else if (position == 2) {//第2个位置是美女布局
return GIRL_VIEW_TYPE;
} else {//其他位置返回正常的布局
return NORMAL_VIEW_TYPE;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
position就是每个item的位置,根据不同的位置来返回不同的布局type,可以根据你的需求自己穿插的来返回不同的viewType
3,根据getItemViewType方法返回的不同的viewType在onCreateViewHolder创建不同的ViewHolder
从这一步开始就是重头戏了
以轮播图为例子,每一个viewType都要有这几个步骤
a,写xml布局:既然有轮播图就肯定有轮播图的布局,我这里用的是第三方的轮播图,看布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="175dp"
app:delay_time="3000"
app:scroll_time="1500"
app:indicator_margin="5dp"
app:indicator_height="6dp"
app:indicator_width="6dp"
app:indicator_drawable_selected="@color/colorPrimary"
app:indicator_drawable_unselected="@color/colorAccent"
/>
</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
没什么别的,就是你要展示的布局文件
b,创建ViewHolder内部类,继承RecyclerView.ViewHolder,在里面实例化你要赋值的控件
/**
* 轮播图的ViewHolder
*/
public static class BannerHolder extends RecyclerView.ViewHolder {
Banner banner;
public BannerHolder(View itemView) {
super(itemView);
banner = (Banner) itemView.findViewById(R.id.banner);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
c,引入布局,new出ViewHolder并将引入的布局传递进去,在onCreateViewHolder方法里面
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
View view = View.inflate(context, R.layout.item_banner, null);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
}
1
2
3
4
5
以上就是为一种布局创建ViewHodler
下面是完整的onCreateViewHolder方法里面判断不同的viewType创建不同的ViewHolder的代码
/**
* 创建ViewHolder,根据getItemViewType方法里面返回的几种类型来创建
*
* @param viewType 就是getItemViewType返回的type
* @return 返回自己创建的ViewHolder
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
view = getView(R.layout.item_banner);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
} else if (viewType == CHANNEL_VIEW_TYPE) {//频道的type
view = getView(R.layout.item_channel);
return new ChannelHolder(view);
} else if (viewType == GIRL_VIEW_TYPE) {//美女
view = getView(R.layout.item_girl);
return new GirlHolder(view);
} else {//正常
view = getView(R.layout.item_normal);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
return new NormalHolder(view);
}
}
/**
* 用来引入布局的方法
*/
private View getView(int view) {
View view1 = View.inflate(context, view, null);
return view1;
}
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
4,onBindViewHolder方法里面用instanceof判断不同的ViewHolder来做不通的赋值处理
直接上代码了,注释很清楚了
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
//判断不同的ViewHolder做不同的处理
if (holder instanceof BannerHolder) {//轮播图
BannerHolder bannerHolder = (BannerHolder) holder;
//调用设置轮播图相关方法
setBanner(bannerHolder);
} else if (holder instanceof ChannelHolder) {//频道
ChannelHolder channelHolder = (ChannelHolder) holder;
//设置频道
setChannel(channelHolder);
} else if (holder instanceof GirlHolder) {//美女
GirlHolder girlHolder = (GirlHolder) holder;
GridViewAdapter adapter = new GridViewAdapter(context, girlList);
girlHolder.gridView.setAdapter(adapter);
girlHolder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(context, "美女" + position, Toast.LENGTH_SHORT).show();
}
});
} else if (holder instanceof NormalHolder) {//正常布局
NormalHolder normalHolder = (NormalHolder) holder;
normalHolder.textView.setText(normalList.get(position - 3));
normalHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "点击了" + normalList.get(position - 3), Toast.LENGTH_SHORT).show();
}
});
}
}
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
5,注意getItemCount的返回值
稍微不注意就越界了,+3是因为除了正常的布局还有3个不同的布局
如果是服务器请求数据的话就得不同的情况不同处理了
@Override
public int getItemCount() {
return normalList.size() + 3;
}
1
2
3
4
下面贴出 整个RecyclerView的adapter的代码
package duanlian.multiplerecyclerviewdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.youth.banner.Banner;
import com.youth.banner.BannerConfig;
import com.youth.banner.Transformer;
import com.youth.banner.loader.ImageLoader;
import java.util.List;
import java.util.Map;
/**
* 程序猿: 段炼
* 创建日期: 2017/4/19
* 创建时间: 9:30
* 本类功能:recyclerView的Adapter
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<String> picList;
private List<Map<String, Object>> channelList;
private List<Integer> girlList;
private List<String> normalList;
private final int BANNER_VIEW_TYPE = 0;//轮播图
private final int CHANNEL_VIEW_TYPE = 1;//频道
private final int GIRL_VIEW_TYPE = 2;//美女
private final int NORMAL_VIEW_TYPE = 3;//正常布局
public RecyclerAdapter(Context context, List<String> picList, List<Map<String, Object>> channelList,
List<Integer> girlList, List<String> normalList) {
this.context = context;
this.picList = picList;
this.channelList = channelList;
this.girlList = girlList;
this.normalList = normalList;
}
/**
* 获取item的类型
*
* @param position item的位置
* @return item的类型
* 有几种type就回在onCreateViewHolder方法中引入几种布局,也就是创建几个ViewHolder
*/
@Override
public int getItemViewType(int position) {
/*
区分item类型,返回不同的int类型的值
在onCreateViewHolder方法中用viewType来创建不同的ViewHolder
*/
if (position == 0) {//第0个位置是轮播图
return BANNER_VIEW_TYPE;
} else if (position == 1) {//第一个是频道布局
return CHANNEL_VIEW_TYPE;
} else if (position == 2) {//第2个位置是美女布局
return GIRL_VIEW_TYPE;
} else {//其他位置返回正常的布局
return NORMAL_VIEW_TYPE;
}
}
/**
* 创建ViewHolder,根据getItemViewType方法里面返回的几种类型来创建
*
* @param viewType 就是getItemViewType返回的type
* @return 返回自己创建的ViewHolder
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == BANNER_VIEW_TYPE) {//如果viewType是轮播图就去创建轮播图的viewHolder
view = getView(R.layout.item_banner);
BannerHolder bannerHolder = new BannerHolder(view);
return bannerHolder;
} else if (viewType == CHANNEL_VIEW_TYPE) {//频道的type
view = getView(R.layout.item_channel);
return new ChannelHolder(view);
} else if (viewType == GIRL_VIEW_TYPE) {//美女
view = getView(R.layout.item_girl);
return new GirlHolder(view);
} else {//正常
view = getView(R.layout.item_normal);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
return new NormalHolder(view);
}
}
/**
* 用来引入布局的方法
*/
private View getView(int view) {
View view1 = View.inflate(context, view, null);
return view1;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
//判断不同的ViewHolder做不同的处理
if (holder instanceof BannerHolder) {//轮播图
BannerHolder bannerHolder = (BannerHolder) holder;
//调用设置轮播图相关方法
setBanner(bannerHolder);
} else if (holder instanceof ChannelHolder) {//频道
ChannelHolder channelHolder = (ChannelHolder) holder;
//设置频道
setChannel(channelHolder);
} else if (holder instanceof GirlHolder) {//美女
GirlHolder girlHolder = (GirlHolder) holder;
GridViewAdapter adapter = new GridViewAdapter(context, girlList);
girlHolder.gridView.setAdapter(adapter);
girlHolder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(context, "美女" + position, Toast.LENGTH_SHORT).show();
}
});
} else if (holder instanceof NormalHolder) {//正常布局
NormalHolder normalHolder = (NormalHolder) holder;
normalHolder.textView.setText(normalList.get(position - 3));
normalHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "点击了" + normalList.get(position - 3), Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* 设置频道
*
* @param channelHolder
*/
private void setChannel(ChannelHolder channelHolder) {
//动态添加View
for (int i = 0; i < channelList.size(); i++) {
View view = View.inflate(context, R.layout.item_channel_view, null);
ImageView ivLogo = (ImageView) view.findViewById(R.id.iv_logo);
TextView tvChannel = (TextView) view.findViewById(R.id.tv_channel);
Glide.with(context).load(channelList.get(i).get("pic")).into(ivLogo);
tvChannel.setText(channelList.get(i).get("title").toString());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);
params.setMargins(24, 0, 24, 0);
view.setTag(i);
final int finalI = i;
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, channelList.get(finalI).get("title").toString(), Toast.LENGTH_SHORT).show();
}
});
channelHolder.linearLayout.addView(view);
}
}
/**
* 设置轮播图
*
* @param bannerHolder
*/
private void setBanner(BannerHolder bannerHolder) {
//设置banner样式
bannerHolder.banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR);
//设置图片加载器
bannerHolder.banner.setImageLoader(new GlideImageLoader());
//设置图片集合
bannerHolder.banner.setImages(picList);
//设置banner动画效果
bannerHolder.banner.setBannerAnimation(Transformer.Default);
//设置标题集合(当banner样式有显示title时)
// bannerHolder.banner.setBannerTitles(titles);
//设置自动轮播,默认为true
bannerHolder.banner.isAutoPlay(true);
//设置轮播时间
// bannerHolder.banner.setDelayTime(3500);
//设置指示器位置(当banner模式中有指示器时)
bannerHolder.banner.setIndicatorGravity(BannerConfig.CENTER);
//banner设置方法全部调用完毕时最后调用
bannerHolder.banner.start();
}
public class GlideImageLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
//Glide 加载图片简单用法
Glide.with(context).load(path).into(imageView);
}
}
@Override
public int getItemCount() {
return normalList.size() + 3;
}
/*****************************************下面是为不同的布局创建不同的ViewHolder*******************************************************/
/**
* 轮播图的ViewHolder
*/
public static class BannerHolder extends RecyclerView.ViewHolder {
Banner banner;
public BannerHolder(View itemView) {
super(itemView);
banner = (Banner) itemView.findViewById(R.id.banner);
}
}
/**
* 频道列表的ViewHolder
*/
public static class ChannelHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
public ChannelHolder(View itemView) {
super(itemView);
linearLayout = (LinearLayout) itemView.findViewById(R.id.ll_channel);
}
}
/**
* 美女的ViewHolder
*/
public static class GirlHolder extends RecyclerView.ViewHolder {
GridView gridView;
public GirlHolder(View itemView) {
super(itemView);
gridView = (GridView) itemView.findViewById(R.id.gridview);
}
}
/**
* 正常布局的ViewHolder
*/
public static class NormalHolder extends RecyclerView.ViewHolder {
TextView textView;
public NormalHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text);
}
}
}
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
254
255
256
257
258
259
260
261
262
263
还有些细节就不说了,请下载demo
点击下载demo
---------------------
作者:段炼Android
来源:CSDN
原文:https://blog.csdn.net/dl10210950/article/details/70239907
版权声明:本文为博主原创文章,转载请附上博文链接!

浙公网安备 33010602011771号