RecyclerView虽然作为ListView的替代者有着较好的性能提升,但是ListView的一些常用功能却没有提供,比如我们平时会经常用到的addHeaderView,addFooterView,既然RecyclerView没有提供这个方法,我们应该如何为列表添加头部和底部呢,接下来
正文
使用RecyclerView添加Header和Footer的方法
recyclerview与listview原理是类似的:都是仅仅维护少量的view并且可以展示大量的数据集。recyclerview用以下两种方式简化了数据的展示和处理:
使用layoutmanager来确定每一个item的排列方式。
为增加和删除项目提供默认的动画效果。
recyclerview虽然作为listview的替代者有着较好的性能提升,但是listview的一些常用功能却没有提供,比如我们平时会经常用到的addheaderview,addfooterview,既然recyclerview没有提供这个方法,我们应该如何为列表添加头部和底部呢?通过看listview的源码可以知道listview的添加header和footer是靠adapter里面动态添加的,所以我们按照这个思路也给recyclerview添加headerview和footerview,先看一下效果
如果你还不了解recyclerview如何使用,可以看一下前几篇博文

recyclerview实现添加headerview和footerview的核心就是在adapter里面的oncreateviewholder根据viewtype来判断是列表项还是headerview来分别加载不同的布局文件,当然viewtype的判断规则也是由我们定义的,废话不多说,看一下具体的实现效果。
1:gradle配置 build.gradle
|
1
2
|
compile 'com.android.support:recyclerview-v7:23.1.1'compile 'com.android.support:cardview-v7:23.1.1' |
2:主布局文件 activity_main.xml 很简单里面一个recyclerview
|
1
2
3
4
5
6
7
8
9
10
11
|
<?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="match_parent"><android.support.v7.widget.recyclerviewxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/rv_list"/></linearlayout> |
3:列表项布局 rv_item.xml 外面一个cardview的卡片式容器里面一个textview
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.cardviewxmlns:card_view="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:id="@+id/cv_item"android:foreground="?android:attr/selectableitembackground"card_view:cardcornerradius="4dp"card_view:cardelevation="4dp"><linearlayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><textviewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_item_text"android:text="test"android:layout_margin="8dp"/></linearlayout></android.support.v7.widget.cardview> |
4:列表头部布局 rv_header.xml
|
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
|
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.cardviewxmlns:card_view="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:id="@+id/cv_item"android:foreground="?android:attr/selectableitembackground"card_view:cardcornerradius="4dp"card_view:cardelevation="4dp"card_view:cardbackgroundcolor="#4caf50"><linearlayoutandroid:layout_width="match_parent"android:layout_height="150dp"><textviewandroid:layout_width="match_parent"android:layout_height="match_parent"android:text="header"android:textsize="30sp"android:textcolor="#ffffff"android:gravity="center"/></linearlayout></android.support.v7.widget.cardview> |
5:列表底部布局 rv_footer.xml
|
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
|
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.cardviewxmlns:card_view="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="8dp"android:id="@+id/cv_item"android:foreground="?android:attr/selectableitembackground"card_view:cardcornerradius="4dp"card_view:cardelevation="4dp"card_view:cardbackgroundcolor="#e91e63"><linearlayoutandroid:layout_width="match_parent"android:layout_height="150dp"><textviewandroid:layout_width="match_parent"android:layout_height="match_parent"android:text="footer"android:textsize="30sp"android:textcolor="#ffffff"android:gravity="center"/></linearlayout></android.support.v7.widget.cardview> |
6:*headerbottomadapter.java,recyclerview的adapter,在getitemviewtype方法里面判断了当前item的类型,然后在oncreateviewholder跟据item的类型分别加载不同的布局以实现headerview和footerview,其他方法的含义可以参考注释
|
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
|
import android.content.context;import android.support.v7.widget.recyclerview;import android.view.layoutinflater;import android.view.view;import android.view.viewgroup;import android.widget.textview;/*** created by lijizhou on 2016/2/24.* blog:http://blog.csdn.net/leejizhou* qq:3107777777*/public class headerbottomadapter extends recyclerview.adapter<recyclerview.viewholder> {//item类型public static final int item_type_header = 0;public static final int item_type_content = 1;public static final int item_type_bottom = 2;//模拟数据public string [] texts={"java","python","c++","php",".net","js","ruby","swift","oc"};private layoutinflater mlayoutinflater;private context mcontext;private int mheadercount=1;//头部view个数private int mbottomcount=1;//底部view个数public headerbottomadapter(context context) {mcontext = context;mlayoutinflater = layoutinflater.from(context);}//内容长度public int getcontentitemcount(){return texts.length;}//判断当前item是否是headviewpublic boolean isheaderview(int position) {return mheadercount != 0 && position < mheadercount;}//判断当前item是否是footerviewpublic boolean isbottomview(int position) {return mbottomcount != 0 && position >= (mheadercount + getcontentitemcount());}//判断当前item类型@overridepublic int getitemviewtype(int position) {int dataitemcount = getcontentitemcount();if (mheadercount != 0 && position < mheadercount) {//头部viewreturn item_type_header;} else if (mbottomcount != 0 && position >= (mheadercount + dataitemcount)) {//底部viewreturn item_type_bottom;} else {//内容viewreturn item_type_content;}}//内容 viewholderpublic static class contentviewholder extends recyclerview.viewholder {private textview textview;public contentviewholder(view itemview) {super(itemview);textview=(textview)itemview.findviewbyid(r.id.tv_item_text);}}//头部 viewholderpublic static class headerviewholder extends recyclerview.viewholder {public headerviewholder(view itemview) {super(itemview);}}//底部 viewholderpublic static class bottomviewholder extends recyclerview.viewholder {public bottomviewholder(view itemview) {super(itemview);}}@overridepublic recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) {if (viewtype ==item_type_header) {return new headerviewholder(mlayoutinflater.inflate(r.layout.rv_header, parent, false));} else if (viewtype == mheadercount) {return new contentviewholder(mlayoutinflater.inflate(r.layout.rv_item, parent, false));} else if (viewtype == item_type_bottom) {return new bottomviewholder(mlayoutinflater.inflate(r.layout.rv_footer, parent, false));}return null;}@overridepublic void onbindviewholder(recyclerview.viewholder holder, int position) {if (holder instanceof headerviewholder) {} else if (holder instanceof contentviewholder) {((contentviewholder) holder).textview.settext(texts[position - mheadercount]);} else if (holder instanceof bottomviewholder) {}}@overridepublic int getitemcount() {return mheadercount + getcontentitemcount() + mbottomcount;}} |
7:最后一步,mainactivity.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
|
import android.support.v7.app.appcompatactivity;import android.os.bundle;import android.support.v7.widget.gridlayoutmanager;import android.support.v7.widget.linearlayoutmanager;import android.support.v7.widget.recyclerview;public class mainactivity extends appcompatactivity {private recyclerview mrecyclerview;private headerbottomadapter adapter;gridlayoutmanager gridlayoutmanager;linearlayoutmanager layoutmanager;@overrideprotected void oncreate(bundle savedinstancestate) {super.oncreate(savedinstancestate);setcontentview(r.layout.activity_main);mrecyclerview=(recyclerview)findviewbyid(r.id.rv_list);//list布局layoutmanager=new linearlayoutmanager(this);layoutmanager.setorientation(linearlayoutmanager.vertical);mrecyclerview.setlayoutmanager(layoutmanager);mrecyclerview.setadapter(adapter=new headerbottomadapter(this));//grid布局 // gridlayoutmanager=new gridlayoutmanager(mainactivity.this, 2);// mrecyclerview.setlayoutmanager(gridlayoutmanager);//这里用线性宫格显示 类似于grid view// mrecyclerview.setadapter(adapter=new headerbottomadapter(this));////// gridlayoutmanager.setspansizelookup(new gridlayoutmanager.spansizelookup() {// @override// public int getspansize(int position) {// return (adapter.isheaderview(position) || adapter.isbottomview(position)) ? gridlayoutmanager.getspancount() : 1;// }// });}} |
这里注意一点,如果你的recyclerview使用grid类型列表在设置adapter后需要调用这个方法,根据当前item类型来判断占据的横向格数,这也是adapter里面实现isheaderview和isbottomview的缘故
|
1
2
3
4
5
6
|
gridlayoutmanager.setspansizelookup(new gridlayoutmanager.spansizelookup() {@overridepublic int getspansize(int position) {return (adapter.isheaderview(position) || adapter.isbottomview(position)) ? gridlayoutmanager.getspancount() : 1;}}); |
ok,recyclerview添加header和footer就这样轻松实现了,你也可以把adapter再次封装更有利于日常的开发。
关于使用recyclerview添加header和footer的方法就给大家介绍到这里,希望对大家有所帮助!

发表评论