Android RecyclerView Adapter with Header and footer inside fragment

In my previous post we show you how to use RecyclerView with the header. In this post, I will show you how to create a RecyclerView adapter for a fragment which should have inbuilt header and footer and we can dynamically show or hide the header and footer as per our requirement.

Create Project

First of all, create a project with the name of RecyclerViewFragment and use the empty Activity and put all other things as default. By default, a MainActivity.java will get created and a layout XML file will get created.
Adapter with Header and Footer

Here we create an adapter which we will use with the fragment. Just go step by step to create our adapter.

Constructor of Adapter

public Adapter(Context context, List<String> data, boolean isHeader, boolean isFooter){  
   this.context=context;  
   this.data=data;  
   this.isHeader=isHeader;  
   this.isFooter=isFooter;  
 }  

Above you can see that we have four parameters in the constructor of the adapter.

context — Context reference of the parent.
data — Data which will be displayed on the RecylcerView
isHeader — It is Boolean variable to check whether Header View required or not

isFooter — It is Boolean variable to check whether Footer View required or not.

CreateViewHolder Method to show the header and footer

In this part, we are creating the view dynamically as required if we required Header View then we inflate the header view, if we required Footer then we will inflate the footer view.

 @Override  
 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
   if(viewType==VIEW_HEADER) {  
     return new headView(LayoutInflater.from(context).inflate(R.layout.header, parent, false));  
   }  
   else if (viewType==VIEW_FOOTER){  
     return new footerView(LayoutInflater.from(context).inflate(R.layout.footer, parent, false));  
   }  
   else {  
     return new itemView(LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false));  
   }  
 }  

OnBindViewHolder Method

In this part, we are overriding onBindViewHolder method of adapter to perform the action as required. If we have to show header then we will perform the action as required by header view, if we have show footer then we will perform the action as required for footerview.

 @Override  
 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
   if(holder instanceof headView){  
     ((headView) holder).header.setText("This is Header");  
     Log.d("Item View","Binding Item header at"+position);  
   }  
   else if(holder instanceof footerView) {  
     ((footerView) holder).footer.setText("This is Footer");  
   }  
   else {  
     ((itemView) holder).itemName.setText(getName(position));  
     Log.d("Item View","Binding Item "+position);  
   }  
 }  

How to get count of the Item in Recylerview

Using this method we get the count of the item in our recyclerview. It will be used to dynamically change the item count in recycler view depnding on header, footer and actual item count.

 @Override  
 public int getItemCount() {  
   int itemCount=data.size();  
   //if header is required then increase the number of count by one  if(isHeader){  
     itemCount=itemCount+1;  
   }  
   if( isFooter){  
     itemCount=itemCount+1;  
   }  
   return itemCount;  
 }  

How to get the data dynamically by type of Recyclerview

This is the sample method to get the dynamic data depending on the type of the recyclerview. You can create the other similar method to get the data as per your

 public String getName(int position){  
   if(isHeader){  
     return data.get(position-1);  
   }  
   else return data.get(position);  
 }  

How to get the type of the View

Here we are overriding the method getItemViewType to get the type of the view depending on the position of the view. There are two important method which are used in conjunction with these two method fist on isFooter and second is isHeader. In both method we call with position of the view and method return true or false.

 @Override  
 public int getItemViewType(int position) {  
   if (isHeader && isHeader(position))  
     return VIEW_HEADER;  
   else if (isFooter && isFooter(position)){  
     return VIEW_FOOTER;  
   }  
   else return VIEW_ITEM;  
 }  
 private boolean isFooter(int position) {  
   return position==getItemCount()-1;  
 }  
 private boolean isHeader(int position)   
 {   
 return position == 0;   
  }  

Create the View Holder for Header, Footer and Item of RecyclerView

Below is the three type of the view holder which we are using in this example, making it simple so you should grab it easily. As per their name headView is the view holder for header, footerView is the view holder for footer and itemView is the view holder for the item inside our recyclerview.

 public class headView extends RecyclerView.ViewHolder {  
   protected TextView header;  
   public headView(View v) {  
     super(v);  
     header = (TextView) v.findViewById(R.id.header);  
   }  
 }  
 public class footerView extends RecyclerView.ViewHolder {  
   protected TextView footer;  
   public footerView(View v) {  
     super(v);  
     footer = (TextView) v.findViewById(R.id.footer);  
   }  
 }  
 public class itemView extends RecyclerView.ViewHolder {  
   protected TextView itemName;  
   public itemView(View v) {  
     super(v);  
     itemName = (TextView) v.findViewById(R.id.item_name);  
   }}   

Adapter to show the header and footer with fragement

 package com.debugandroid.RecyclerViewFragment;  
 import android.content.Context;  
 import android.support.v7.widget.RecyclerView;  
 import android.util.Log;  
 import android.view.LayoutInflater;  
 import android.view.View;  
 import android.view.ViewGroup;  
 import android.widget.TextView;  
 import java.util.List;  
 /**  
  * Created by PK on 9/20/2016.  
  */  
 public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {  
   private boolean isHeader;  
   private boolean isFooter;  
   private List<String> data;  
   private Context context;  
   public static final int VIEW_HEADER = 0;  
   public static final int VIEW_FOOTER = 2;  
   public static final int VIEW_ITEM = 1;  
   public Adapter(Context context, List<String> data, boolean isHeader, boolean isFooter){  
     this.context=context;  
     this.data=data;  
     this.isHeader=isHeader;  
     this.isFooter=isFooter;  
   }  
   @Override  
   public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
     if(viewType==VIEW_HEADER) {  
       return new headView(LayoutInflater.from(context).inflate(R.layout.header, parent, false));  
     }  
     else if (viewType==VIEW_FOOTER){  
       return new footerView(LayoutInflater.from(context).inflate(R.layout.footer, parent, false));  
     }  
     else {  
       return new itemView(LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false));  
     }  
   }  
   @Override  
   public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
     if(holder instanceof headView){  
       ((headView) holder).header.setText("This is Header");  
       Log.d("Item View","Binding Item header at"+position);  
     }  
     else if(holder instanceof footerView) {  
       ((footerView) holder).footer.setText("This is Footer");  
     }  
     else {  
       ((itemView) holder).itemName.setText(getName(position));  
       Log.d("Item View","Binding Item "+position);  
     }  
   }  
 // to Check the number of item  
   @Override  
   public int getItemCount() {  
     int itemCount=data.size();  
     //if header is required then increase the number of count by one  
     if(isHeader){  
       itemCount=itemCount+1;  
     }  
     if( isFooter){  
       itemCount=itemCount+1;  
     }  
     return itemCount;  
   }  
   public String getName(int position){  
     if(isHeader){  
       return data.get(position-1);  
     }  
     else return data.get(position);  
   }  
   @Override  
   public int getItemViewType(int position) {  
     if (isHeader && isHeader(position))  
       return VIEW_HEADER;  
     else if (isFooter && isFooter(position)){  
       return VIEW_FOOTER;  
     }  
     else return VIEW_ITEM;  
   }  
   private boolean isFooter(int position) {  
     return position==getItemCount()-1;  
   }  
   private boolean isHeader(int position) { return position == 0;  }  
   public class headView extends RecyclerView.ViewHolder {  
     protected TextView header;  
     public headView(View v) {  
       super(v);  
       header = (TextView) v.findViewById(R.id.header);  
     }  
   }  
   public class footerView extends RecyclerView.ViewHolder {  
     protected TextView footer;  
     public footerView(View v) {  
       super(v);  
       footer = (TextView) v.findViewById(R.id.footer);  
     }  
   }  
   public class itemView extends RecyclerView.ViewHolder {  
     protected TextView itemName;  
     public itemView(View v) {  
       super(v);  
       itemName = (TextView) v.findViewById(R.id.item_name);  
     }  
   }  
 }  

Creating Fragment for our header and footer demo of recycler view

Now we have create the fragment which will be used with recyclerview, so create a class with the name of MyFragment.java and modify it as given below.

 package com.debugandroid.RecyclerViewFragment;  
 import android.os.Bundle;  
 import android.support.v4.app.Fragment;  
 import android.support.v7.widget.GridLayoutManager;  
 import android.support.v7.widget.RecyclerView;  
 import android.view.LayoutInflater;  
 import android.view.View;  
 import android.view.ViewGroup;  
 import java.util.ArrayList;  
 import java.util.List;  
 public class MyFragment extends Fragment {  
   private RecyclerView recyclerView;  
   private Adapter adapter;  
   private List<String> data=new ArrayList<String>();  
   public MyFragment() {}  
   @Override  
   public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
   }  
   @Override  
   public View onCreateView(LayoutInflater inflater, ViewGroup container,  
                Bundle savedInstanceState) {  
     // Inflate the layout for this fragment  
     return inflater.inflate(R.layout.fragment_my, container, false);  
   }  
   @Override  
   public void onActivityCreated(Bundle savedInstanceState){  
     super.onActivityCreated(savedInstanceState);  
     recyclerView= (RecyclerView) getActivity().findViewById(R.id.recyclerView);  
     for (int i=0;i<=32;i++){  
       data.add("Item "+i);  
     }  
     GridLayoutManager glm = new GridLayoutManager(getActivity(), 2);  
     glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {  
       @Override public int getSpanSize(int position) {  
         switch (adapter.getItemViewType(position)){  
           case 0: return 2;  
           case 1: return 1;  
           case 2: return 2;  
           default: return 2;  
         }  
       }  
     });  
     recyclerView.setLayoutManager(glm);  
     adapter=new Adapter(getActivity(),data,true,true);  
     recyclerView.setAdapter(adapter);  
   }  
 }  

You can also find the fragment xml and other files on GitHub.

MyFragment.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   xmlns:tools="http://schemas.android.com/tools"  
   android:layout_width="match_parent"  
   android:layout_height="match_parent"  
   tools:context="com.debugandroid.RecyclerViewFragment.MyFragment">  
   <android.support.v7.widget.RecyclerView  
     android:layout_width="match_parent"  
     android:layout_height="match_parent"  
     android:id="@+id/recyclerView">  
   </android.support.v7.widget.RecyclerView>  
 </FrameLayout>  

Binding Fragment with Activity

For binding, the fragment with main activity open the MainActivity.java and modify it as given below.

 public class MainActivity extends AppCompatActivity {  
   private Button btn_load;  
   @Override  protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     Fragment fragment = new MyFragment();  
     FragmentManager fragmentManager = getSupportFragmentManager();  
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();  
     fragmentTransaction.replace(R.id.fragment_holder, fragment);  
     fragmentTransaction.commit();  
   }  
 }    

XML of the MainActivity.java is available here.

Test your application it will look like as given below.

Header and Footer

Source Code on GitHUB

Get Email Updates!

Signup now receive an email once I publish new content. I will never give away, trade or sell your email address. You can unsubscribe at any time.

Join 911 other subscribers

Leave a Reply

Close Menu