Android RecyclerView添加头部和底部实例详解
android recyclerview添加头部和底部实例详解
如果只是想添加头部,可是使用github里面这个项目,它可以为linearlayoutmanager,gridlayoutmanager ,staggeredgridlayoutmanager布局的recyclerview添加header。使用起来也十分简单;
只需将recyclerviewheader布局放在recyclerview的上层。
<framelayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.recyclerview android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|top" /> <com.bartoszlipinski.recyclerviewheader.recyclerviewheader android:id="@+id/header" android:layout_width="match_parent" android:layout_height="100dp" android:layout_gravity="center_horizontal|top"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerinparent="true" android:text="header"/> </com.bartoszlipinski.recyclerviewheader.recyclerviewheader> </framelayout>
然后获得recyclerviewheader对象:
recyclerviewheader header = (recyclerviewheader) findviewbyid(r.id.header);
把recyclerviewheader赋予recyclerview
recyclerview recyclerview = (recyclerview) findviewbyid(r.id.recycler_view); // set layoutmanager for your recyclerview header.attachto(recyclerview, true);
注意事项
recyclerviewheader必须在recyclerview设置了layoutmanager之后调用。
目前该库适用于linearlayoutmanager,staggeredgridlayoutmanager和gridlayoutmanager布局的recyclerviews。只支持垂直布局layoutmanager。如果你打算在recyclerview中使用setonscrolllistener(…)方法,确保在setonscrolllistener(…)的attachto(…)方法之前使用。
当然我们也可以自己写一个添加头部和底部的recyclerview。它实现的基本原理也是通过getitemviewtype方法返回不同的类型来添加头部和底部。
首先我们自定义一个recyclerview:
public class wraprecyclerview extends recyclerview { public arraylist<view> mheaderviews = new arraylist<>(); public arraylist<view> mfooterviews = new arraylist<>(); //添加adapter public adapter madapter; public wraprecyclerview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); } public wraprecyclerview(context context, attributeset attrs) { super(context, attrs); } public wraprecyclerview(context context) { super(context); } public void addheaderview(view view){ mheaderviews.clear(); mheaderviews.add(view); if(madapter!=null){ if(!(madapter instanceof recyclerwrapadapter)){ madapter = new recyclerwrapadapter(mheaderviews,mfooterviews,madapter); } } } public void addfooterview(view view){ mfooterviews.clear(); mfooterviews.add(view); if(madapter!=null){ if(!(madapter instanceof recyclerwrapadapter)){ madapter = new recyclerwrapadapter(mheaderviews,mfooterviews,madapter); } } } public void setadapter(adapter adapter){ if (mheaderviews.isempty()&&mfooterviews.isempty()){ super.setadapter(adapter); }else { adapter = new recyclerwrapadapter(mheaderviews,mfooterviews,adapter) ; super.setadapter(adapter); } madapter = adapter ; } }
我们会看到我们有一个recyclerwrapadapter没有实现,下面我们就来看下recyclerwrapadapter,这个也是实现添加头部和尾部的关键。
public class recyclerwrapadapter extends recyclerview.adapter implements wrapperadapter{ private recyclerview.adapter madapter; private arraylist<view> mheaderviews; private arraylist<view> mfootviews; static final arraylist<view> empty_info_list = new arraylist<view>(); private int mcurrentposition; public recyclerwrapadapter(arraylist<view> mheaderviews, arraylist<view> mfootviews, recyclerview.adapter madapter){ this.madapter = madapter; if (mheaderviews == null) { this.mheaderviews = empty_info_list; } else { this.mheaderviews = mheaderviews; } if (mfootviews == null) { this.mfootviews = empty_info_list; } else { this.mfootviews = mfootviews; } } public int getheaderscount() { return mheaderviews.size(); } public int getfooterscount() { return mfootviews.size(); } @override public recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) { if (viewtype == recyclerview.invalid_type) { return new headerviewholder(mheaderviews.get(0)); } else if (viewtype == recyclerview.invalid_type - 1) { return new headerviewholder(mfootviews.get(0)); } return madapter.oncreateviewholder(parent, viewtype); } @override public void onbindviewholder(recyclerview.viewholder holder, int position) { //如果头部不为空,那么我们就要先添加头部,所以我们只要 //把前面几个position给头部,当position小于头部总数的时候, //我们返回头部view。再判断原adapter 的 count 与当前 position // 的差值来比较,是调用原 adapter 的 getview 方法,还是获取 footview // 的 view。 int numheaders = getheaderscount(); if (position < numheaders) { return; } int adjposition = position - numheaders; int adaptercount = 0; if (madapter != null) { adaptercount = madapter.getitemcount(); if (adjposition < adaptercount) { madapter.onbindviewholder(holder, adjposition); return; } } } @override public int getitemcount() { if (madapter != null) { return getheaderscount() + getfooterscount() + madapter.getitemcount(); } else { return getheaderscount() + getfooterscount(); } } @override public recyclerview.adapter getwrappedadapter() { return madapter; } @override public int getitemviewtype(int position) { //增加两个类型 //recyclerview.invalid_type 添加头部 //recyclerview.invalid_type-1 添加尾部 //如果头部不为空,那么我们就要先添加头部,所以我们只要 //把前面几个position给头部,当position小于头部总数的时候, //我们返回头部类型。再判断原adapter 的 count 与当前 position // 的差值来比较,是调用原 adapter 的 类型,还是获取 footview // 的类型。 mcurrentposition = position ; int numheaders = getheaderscount(); if(position<numheaders){ return recyclerview.invalid_type ; } int adjposition = position - numheaders ; int adaptercount = 0 ; if(madapter!=null){ adaptercount = madapter.getitemcount() ; if(adjposition < adaptercount){ return madapter.getitemviewtype(adjposition); } } return recyclerview.invalid_type - 1; } private static class headerviewholder extends recyclerview.viewholder { public headerviewholder(view itemview) { super(itemview); } } }
我们还可以实现一个接口,来调用recyclerwrapadapter对象:
public interface wrapperadapter { public recyclerview.adapter getwrappedadapter() ; }
这样我们就可以把recyclerview布局改成wraprecyclerview就可以了,然后调用addheaderview或者addfooterview就可以添加头部和尾部了。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!