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

Android RecyclerView添加头部和底部实例详解

程序员文章站 2023-11-30 22:57:28
android recyclerview添加头部和底部实例详解 如果只是想添加头部,可是使用github里面这个项目,它可以为linearlayoutmanager,gr...

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就可以添加头部和尾部了。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!