RecyclerView添加Header和Footer

转自:http://blog.csdn.net/leejizhou/article/details/50742544

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

如果你还不了解RecyclerView如何使用,可以看一下前几篇博文 
RecyclerView的使用(1)之HelloWorld 
RecyclerView的使用(2)之多Item布局的加载

这里写图片描述 这里写图片描述

RecyclerView实现添加HeaderView和FooterView的核心就是在Adapter里面的onCreateViewHolder根据viewType来判断是列表项还是HeaderView来分别加载不同的布局文件,当然viewType的判断规则也是由我们定义的,废话不多说,看一下具体的实现效果。

1:Gradle配置 build.gradle

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. compile 'com.android.support:recyclerview-v7:23.1.1'  
  2. compile 'com.android.support:cardview-v7:23.1.1'  


2:主布局文件 activity_main.xml 很简单里面一个RecyclerView

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent">  
  5.     <android.support.v7.widget.RecyclerView  
  6.         xmlns:android="http://schemas.android.com/apk/res/android"  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="match_parent"  
  9.         android:id="@+id/rv_list"  
  10.         />  
  11. </LinearLayout>  

3:列表项布局 rv_item.xml 外面一个CardView的卡片式容器里面一个TextView

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.CardView  
  3.     xmlns:card_view="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:android="http://schemas.android.com/apk/res/android"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:layout_margin="8dp"  
  8.     android:id="@+id/cv_item"  
  9.     android:foreground="?android:attr/selectableItemBackground"  
  10.     card_view:cardCornerRadius="4dp"  
  11.     card_view:cardElevation="4dp"  
  12.     >  
  13.     <LinearLayout  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="wrap_content">  
  16.         <TextView  
  17.             android:layout_width="wrap_content"  
  18.             android:layout_height="wrap_content"  
  19.             android:id="@+id/tv_item_text"  
  20.             android:text="test"  
  21.             android:layout_margin="8dp"  
  22.             />  
  23.     </LinearLayout>  
  24.   
  25. </android.support.v7.widget.CardView>  



4:列表头部布局 rv_header.xml

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.CardView  
  3.     xmlns:card_view="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:android="http://schemas.android.com/apk/res/android"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:layout_margin="8dp"  
  8.     android:id="@+id/cv_item"  
  9.     android:foreground="?android:attr/selectableItemBackground"  
  10.     card_view:cardCornerRadius="4dp"  
  11.     card_view:cardElevation="4dp"  
  12.     card_view:cardBackgroundColor="#4CAF50"  
  13.     >  
  14.     <LinearLayout  
  15.         android:layout_width="match_parent"  
  16.         android:layout_height="150dp"  
  17.         >  
  18.         <TextView  
  19.             android:layout_width="match_parent"  
  20.             android:layout_height="match_parent"  
  21.             android:text="Header"  
  22.             android:textSize="30sp"  
  23.             android:textColor="#ffffff"  
  24.             android:gravity="center"  
  25.             />  
  26.     </LinearLayout>  
  27. </android.support.v7.widget.CardView>  



5:列表底部布局 rv_footer.xml

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.CardView  
  3.     xmlns:card_view="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:android="http://schemas.android.com/apk/res/android"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:layout_margin="8dp"  
  8.     android:id="@+id/cv_item"  
  9.     android:foreground="?android:attr/selectableItemBackground"  
  10.     card_view:cardCornerRadius="4dp"  
  11.     card_view:cardElevation="4dp"  
  12.     card_view:cardBackgroundColor="#E91E63"  
  13.     >  
  14.     <LinearLayout  
  15.         android:layout_width="match_parent"  
  16.         android:layout_height="150dp"  
  17.         >  
  18.         <TextView  
  19.             android:layout_width="match_parent"  
  20.             android:layout_height="match_parent"  
  21.             android:text="Footer"  
  22.             android:textSize="30sp"  
  23.             android:textColor="#ffffff"  
  24.             android:gravity="center"  
  25.             />  
  26.   
  27.     </LinearLayout>  
  28. </android.support.v7.widget.CardView>  



6:*HeaderBottomAdapter.java,RecyclerView的Adapter,在getItemViewType方法里面判断了当前Item的类型,然后在onCreateViewHolder跟据item的类型分别加载不同的布局以实现HeaderView和FooterView,其他方法的含义可以参考注释

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import android.content.Context;  
  2. import android.support.v7.widget.RecyclerView;  
  3. import android.view.LayoutInflater;  
  4. import android.view.View;  
  5. import android.view.ViewGroup;  
  6. import android.widget.TextView;  
  7.   
  8. /** 
  9.  * Created by Lijizhou on 2016/2/24. 
  10.  * Blog:http://blog.csdn.net/leejizhou 
  11.  * QQ:3107777777 
  12.  */  
  13. public class HeaderBottomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {  
  14.   
  15.     //item类型  
  16.     public static final int ITEM_TYPE_HEADER = 0;  
  17.     public static final int ITEM_TYPE_CONTENT = 1;  
  18.     public static final int ITEM_TYPE_BOTTOM = 2;  
  19.     //模拟数据  
  20.     public String [] texts={"java","python","C++","Php",".NET","js","Ruby","Swift","OC"};  
  21.     private LayoutInflater mLayoutInflater;  
  22.     private Context mContext;  
  23.     private int mHeaderCount=1;//头部View个数  
  24.     private int mBottomCount=1;//底部View个数  
  25.   
  26.     public HeaderBottomAdapter(Context context) {  
  27.         mContext = context;  
  28.         mLayoutInflater = LayoutInflater.from(context);  
  29.     }  
  30.   
  31.     //内容长度  
  32.     public int getContentItemCount(){  
  33.         return texts.length;  
  34.     }  
  35.     //判断当前item是否是HeadView  
  36.     public boolean isHeaderView(int position) {  
  37.         return mHeaderCount != 0 && position < mHeaderCount;  
  38.     }  
  39.     //判断当前item是否是FooterView  
  40.     public boolean isBottomView(int position) {  
  41.         return mBottomCount != 0 && position >= (mHeaderCount + getContentItemCount());  
  42.     }  
  43.   
  44.   
  45.     //判断当前item类型  
  46.     @Override  
  47.     public int getItemViewType(int position) {  
  48.         int dataItemCount = getContentItemCount();  
  49.         if (mHeaderCount != 0 && position < mHeaderCount) {  
  50.             //头部View  
  51.             return ITEM_TYPE_HEADER;  
  52.         } else if (mBottomCount != 0 && position >= (mHeaderCount + dataItemCount)) {  
  53.             //底部View  
  54.             return ITEM_TYPE_BOTTOM;  
  55.         } else {  
  56.             //内容View  
  57.             return ITEM_TYPE_CONTENT;  
  58.         }  
  59.     }  
  60.   
  61.     //内容 ViewHolder  
  62.     public static class ContentViewHolder extends RecyclerView.ViewHolder {  
  63.         private TextView textView;  
  64.         public ContentViewHolder(View itemView) {  
  65.             super(itemView);  
  66.             textView=(TextView)itemView.findViewById(R.id.tv_item_text);  
  67.         }  
  68.     }  
  69.     //头部 ViewHolder  
  70.     public static class HeaderViewHolder extends RecyclerView.ViewHolder {  
  71.   
  72.         public HeaderViewHolder(View itemView) {  
  73.             super(itemView);  
  74.         }  
  75.     }  
  76.     //底部 ViewHolder  
  77.     public static class BottomViewHolder extends RecyclerView.ViewHolder {  
  78.   
  79.         public BottomViewHolder(View itemView) {  
  80.             super(itemView);  
  81.         }  
  82.     }  
  83.   
  84.     @Override  
  85.     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  86.         if (viewType ==ITEM_TYPE_HEADER) {  
  87.             return new HeaderViewHolder(mLayoutInflater.inflate(R.layout.rv_header, parent, false));  
  88.         } else if (viewType == mHeaderCount) {  
  89.             return  new ContentViewHolder(mLayoutInflater.inflate(R.layout.rv_item, parent, false));  
  90.         } else if (viewType == ITEM_TYPE_BOTTOM) {  
  91.             return new BottomViewHolder(mLayoutInflater.inflate(R.layout.rv_footer, parent, false));  
  92.         }  
  93.         return null;  
  94.     }  
  95.   
  96.     @Override  
  97.     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
  98.         if (holder instanceof HeaderViewHolder) {  
  99.   
  100.         } else if (holder instanceof ContentViewHolder) {  
  101.             ((ContentViewHolder) holder).textView.setText(texts[position - mHeaderCount]);  
  102.   
  103.         } else if (holder instanceof BottomViewHolder) {  
  104.   
  105.         }  
  106.     }  
  107.   
  108.     @Override  
  109.     public int getItemCount() {  
  110.        return mHeaderCount + getContentItemCount() + mBottomCount;  
  111.     }  
  112.   
  113.   
  114.   
  115. }  


7:最后一步,MainActivity.java

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import android.support.v7.app.AppCompatActivity;  
  2. import android.os.Bundle;  
  3. import android.support.v7.widget.GridLayoutManager;  
  4. import android.support.v7.widget.LinearLayoutManager;  
  5. import android.support.v7.widget.RecyclerView;  
  6.   
  7. public class MainActivity extends AppCompatActivity {  
  8.     private RecyclerView mRecyclerView;  
  9.     private HeaderBottomAdapter adapter;  
  10.     GridLayoutManager gridLayoutManager;  
  11.     LinearLayoutManager layoutManager;  
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.activity_main);  
  16.         mRecyclerView=(RecyclerView)findViewById(R.id.rv_list);  
  17.         //List布局  
  18.         layoutManager=new LinearLayoutManager(this);  
  19.         layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  
  20.         mRecyclerView.setLayoutManager(layoutManager);  
  21.         mRecyclerView.setAdapter(adapter=new HeaderBottomAdapter(this));  
  22.   
  23.         //Grid布局   
  24. //        gridLayoutManager=new GridLayoutManager(MainActivity.this, 2);  
  25. //        mRecyclerView.setLayoutManager(gridLayoutManager);//这里用线性宫格显示 类似于grid view  
  26. //        mRecyclerView.setAdapter(adapter=new HeaderBottomAdapter(this));  
  27. //  
  28. //  
  29. //            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {  
  30. //                @Override  
  31. //                public int getSpanSize(int position) {  
  32. //                    return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1;  
  33. //                }  
  34. //            });  
  35.   
  36.   
  37.   
  38.     }  
  39.   
  40.   
  41. }  


这里注意一点,如果你的RecyclerView使用Grid类型列表在设置Adapter后需要调用这个方法,根据当前Item类型来判断占据的横向格数,这也是Adapter里面实现isHeaderView和isBottomView的缘故

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {  
  2.                 @Override  
  3.                 public int getSpanSize(int position) {  
  4.                     return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1;  
  5.                 }  
  6.            });  

Ok,RecyclerView添加Header和Footer就这样轻松实现了,你也可以把Adapter再次封装更有利于日常的开发,本篇博文的源码下载地址http://download.csdn.net/detail/oshenli1/9487599

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值