使用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
compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1'
2:主布局文件 activity_main.xml 很简单里面一个recyclerview
<?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.recyclerview xmlns: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
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.cardview xmlns: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" > <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content"> <textview android: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
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.cardview xmlns: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" > <linearlayout android:layout_width="match_parent" android:layout_height="150dp" > <textview android: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
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.cardview xmlns: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" > <linearlayout android:layout_width="match_parent" android:layout_height="150dp" > <textview android: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,其他方法的含义可以参考注释
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是否是headview public boolean isheaderview(int position) { return mheadercount != 0 && position < mheadercount; } //判断当前item是否是footerview public boolean isbottomview(int position) { return mbottomcount != 0 && position >= (mheadercount + getcontentitemcount()); } //判断当前item类型 @override public int getitemviewtype(int position) { int dataitemcount = getcontentitemcount(); if (mheadercount != 0 && position < mheadercount) { //头部view return item_type_header; } else if (mbottomcount != 0 && position >= (mheadercount + dataitemcount)) { //底部view return item_type_bottom; } else { //内容view return item_type_content; } } //内容 viewholder public static class contentviewholder extends recyclerview.viewholder { private textview textview; public contentviewholder(view itemview) { super(itemview); textview=(textview)itemview.findviewbyid(r.id.tv_item_text); } } //头部 viewholder public static class headerviewholder extends recyclerview.viewholder { public headerviewholder(view itemview) { super(itemview); } } //底部 viewholder public static class bottomviewholder extends recyclerview.viewholder { public bottomviewholder(view itemview) { super(itemview); } } @override public 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; } @override public 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) { } } @override public int getitemcount() { return mheadercount + getcontentitemcount() + mbottomcount; } }
7:最后一步,mainactivity.java
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; @override protected 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的缘故
gridlayoutmanager.setspansizelookup(new gridlayoutmanager.spansizelookup() { @override public int getspansize(int position) { return (adapter.isheaderview(position) || adapter.isbottomview(position)) ? gridlayoutmanager.getspancount() : 1; } });
ok,recyclerview添加header和footer就这样轻松实现了,你也可以把adapter再次封装更有利于日常的开发。
关于使用recyclerview添加header和footer的方法就给大家介绍到这里,希望对大家有所帮助!
推荐阅读
-
使用RecyclerView添加Header和Footer的方法
-
使用RecyclerView添加Header和Footer的方法
-
详解WordPress中添加和执行动作的函数使用方法
-
在 WordPress 的页眉(header)和页脚(footer)添加代码方法
-
jQuery使用before()和after()在元素前后添加内容的方法教程
-
RecyclView使用详解(四): 添加Header和footer
-
详解WordPress中添加和执行动作的函数使用方法,详解wordpress
-
jQuery使用before()和after()在元素前后添加内容的方法_jquery
-
详解WordPress中添加和执行动作的函数使用方法
-
详解WordPress中添加和执行动作的函数使用方法,详解wordpress_PHP教程