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.RecyclerViewxmlns: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.CardViewxmlns: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid: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.CardViewxmlns: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="150dp"><TextViewandroid: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.CardViewxmlns: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="150dp"><TextViewandroid: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是否是HeadViewpublic boolean isHeaderView(int position) {return mHeaderCount != 0 && position < mHeaderCount;}//判斷當前item是否是FooterViewpublic boolean isBottomView(int position) {return mBottomCount != 0 && position >= (mHeaderCount + getContentItemCount());}//判斷當前item類型@Overridepublic int getItemViewType(int position) {int dataItemCount = getContentItemCount();if (mHeaderCount != 0 && position < mHeaderCount) {//頭部Viewreturn ITEM_TYPE_HEADER;} else if (mBottomCount != 0 && position >= (mHeaderCount + dataItemCount)) {//底部Viewreturn ITEM_TYPE_BOTTOM;} else {//內容Viewreturn ITEM_TYPE_CONTENT;}}//內容 ViewHolderpublic static class ContentViewHolder extends RecyclerView.ViewHolder {private TextView textView;public ContentViewHolder(View itemView) {super(itemView);textView=(TextView)itemView.findViewById(R.id.tv_item_text);}}//頭部 ViewHolderpublic static class HeaderViewHolder extends RecyclerView.ViewHolder {public HeaderViewHolder(View itemView) {super(itemView);}}//底部 ViewHolderpublic static class BottomViewHolder extends RecyclerView.ViewHolder {public BottomViewHolder(View itemView) {super(itemView);}}@Overridepublic 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;}@Overridepublic 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) {}}@Overridepublic 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;@Overrideprotected 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() {@Overridepublic int getSpanSize(int position) {return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1;}});Ok,RecyclerView添加Header和Footer就這樣輕松實現了,你也可以把Adapter再次封裝更有利于日常的開發。
關于使用RecyclerView添加Header和Footer的方法就給大家介紹到這里,希望對大家有所幫助!
新聞熱點
疑難解答