欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

使用RecyclerView添加Header和Footer的方法

程序员文章站 2024-02-24 20:33:04
recyclerview与listview原理是类似的:都是仅仅维护少量的view并且可以展示大量的数据集。recyclerview用以下两种方式简化了数据的展示和处理:...

recyclerview与listview原理是类似的:都是仅仅维护少量的view并且可以展示大量的数据集。recyclerview用以下两种方式简化了数据的展示和处理:

使用layoutmanager来确定每一个item的排列方式。

为增加和删除项目提供默认的动画效果。

recyclerview虽然作为listview的替代者有着较好的性能提升,但是listview的一些常用功能却没有提供,比如我们平时会经常用到的addheaderview,addfooterview,既然recyclerview没有提供这个方法,我们应该如何为列表添加头部和底部呢?通过看listview的源码可以知道listview的添加header和footer是靠adapter里面动态添加的,所以我们按照这个思路也给recyclerview添加headerview和footerview,先看一下效果

如果你还不了解recyclerview如何使用,可以看一下前几篇博文

recyclerview的使用之helloworld

recyclerview的使用之多item布局的加载

使用RecyclerView添加Header和Footer的方法使用RecyclerView添加Header和Footer的方法

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的方法就给大家介绍到这里,希望对大家有所帮助!