RecyclerView动态切换不同布局的方法

说明

看懂这个教程首先要对RecyclerView有所认识,可以查看之前写的笔记。
RecyclerView笔记

最终效果

静态图

分析

要实现这种效果,我们可以仔细分析一下界面,从颜色分类可以发现总共可以分成两类,蓝色和粉色的,而粉色的又可以分成两类,一种是一行有四个,而一种是一行占两个,而这种很明显需要网格布局来实现。

实现

画布局
布局一 item1.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_margin="5dp"
android:id="@+id/tv_item1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:background="@color/colorPrimary"/>
</LinearLayout>


布局二 item2.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_margin="5dp"
android:id="@+id/tv_item2"
android:layout_width="match_parent"
android:background="@color/colorAccent"
android:gravity="center"
android:layout_height="60dp"/>
</LinearLayout>

java文件
适配器
MainAdapter.java

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
public class MainAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//类型标记
public static final int TYPE_1 = 0xff01;
public static final int TYPE_2 = 0xff02;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//切换布局
switch (viewType){
case TYPE_1:
return new Item1Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item1,parent,false));
case TYPE_2:
return new Item2Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item2,parent,false));
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {//绑定控件
if (holder instanceof Item1Holder) {
bindItem1Holder((Item1Holder)holder,position);
}else if(holder instanceof Item2Holder){
bindItem2Holder((Item2Holder)holder,position);
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView 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) {//切换占的格数
if (position == 0||position%7==0) {
return 4;
} else if(position==1||position==2||position==3||position==4
||position%7==1||position%7==2||position%7==3||position%7==4){
return 1;
} else {
return 2;
}
}
});
}
}
@Override
public int getItemCount() {//控件总数量
return 60;
}
@Override
public int getItemViewType(int position) {
if (position == 0||position%7==0) {//返回类型
return TYPE_1;
} else {
return TYPE_2;
}
}
private void bindItem2Holder(Item2Holder holder,int position){//控件处理的地方
if(position==1||position==2||position==3||position==4
||position%7==1||position%7==2||position%7==3||position%7==4){
holder.tvItem2.setText("界面2");
} else {
holder.tvItem2.setText("界面3");
}
}
private void bindItem1Holder(Item1Holder holder,int position){
holder.tvItem1.setText("界面1");
}
public class Item1Holder extends RecyclerView.ViewHolder {//设置控件
private TextView tvItem1;
public Item1Holder(View itemView) {
super(itemView);
tvItem1 = (TextView) itemView.findViewById(R.id.tv_item1);
}
}
public class Item2Holder extends RecyclerView.ViewHolder {
private TextView tvItem2;
public Item2Holder(View itemView) {
super(itemView);
tvItem2 = (TextView) itemView.findViewById(R.id.tv_item2);
}
}
}

其中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public int getItemViewType(int position) {
if (position == 0||position%7==0) {//返回类型
return TYPE_1;
} else {
return TYPE_2;
}
}
.......
.......
if (position == 0||position%7==0) {
return 4;
} else if(position==1||position==2||position==3||position==4
||position%7==1||position%7==2||position%7==3||position%7==4){
return 1;
} else {
return 2;
}


是利用不同的个数设定返回的布局类型以及根据不同的个数设定的占的格数,根据规律利用一点数学知识实现,实际开发应该设定标记位

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private MainAdapter mMainAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainAdapter=new MainAdapter();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));//设置一行有四格的网格布局
mRecyclerView.setAdapter(mMainAdapter);
}
}

Done!