Skip to content

Instantly share code, notes, and snippets.

@willblaschko
Created November 13, 2015 00:50
Show Gist options
  • Save willblaschko/1113be1eaff048a6ed14 to your computer and use it in GitHub Desktop.
Save willblaschko/1113be1eaff048a6ed14 to your computer and use it in GitHub Desktop.
public class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
//our items
List<Generic> items = new Arraylist<>();
//headers
List<View> headers = new ArrayList<>();
//footers
List<View> footers = new ArrayList<>();
public static final int TYPE_HEADER = 111;
public static final int TYPE_FOOTER = 222;
public static final int TYPE_ITEM = 333;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
//if our position is one of our items (this comes from getItemViewType(int position) below)
if(type == TYPE_ITEM) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.generic_layout, viewGroup, false);
return new GenericViewHolder(view);
//else we have a header/footer
}else{
//create a new framelayout, or inflate from a resource
FrameLayout frameLayout = new FrameLayout(viewGroup.getContext());
//make sure it fills the space
frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return new HeaderFooterViewHolder(frameLayout);
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder vh, int position) {
//check what type of view our position is
if(position < headers.size()){
View v = headers.get(position);
//add our view to a header view and display it
prepareHeaderFooter((HeaderFooterViewHolder) vh, v);
}else if(position >= headers.size() + items.size()){
View v = footers.get(position-items.size()-headers.size());
//add oru view to a footer view and display it
prepareHeaderFooter((HeaderFooterViewHolder) vh, v);
}else {
//it's one of our items, display as required
prepareGeneric((GenericViewHolder) vh, position-headers.size());
}
}
@Override
public int getItemCount() {
//make sure the adapter knows to look for all our items, headers, and footers
return headers.size() + items.size() + footers.size();
}
private void prepareHeaderFooter(HeaderFooterViewHolder vh, View view){
//empty out our FrameLayout and replace with our header/footer
vh.base.removeAllViews();
vh.base.addView(view);
}
private void prepareGeneric(GenericViewHolder vh, int position){
//do whatever we need to for our other type
...
}
@Override
public int getItemViewType(int position) {
//check what type our position is, based on the assumption that the order is headers > items > footers
if(position < headers.size()){
return TYPE_HEADER;
}else if(position >= headers.size() + items.size()){
return TYPE_FOOTER;
}
return TYPE_ITEM;
}
//add a header to the adapter
public void addHeader(View header){
if(!headers.contains(header)){
headers.add(header);
//animate
notifyItemInserted(headers.size() - 1);
}
}
//remove a header from the adapter
public void removeHeader(View header){
if(headers.contains(header)){
//animate
notifyItemRemoved(headers.indexOf(header));
headers.remove(header);
if(header.getParent() != null) {
((ViewGroup) header.getParent()).removeView(header);
}
}
}
//add a footer to the adapter
public void addFooter(View footer){
if(!footers.contains(footer)){
footers.add(footer);
//animate
notifyItemInserted(headers.size()+items.size()+footers.size()-1);
}
}
//remove a footer from the adapter
public void removeFooter(View footer){
if(footers.contains(footer)) {
//animate
notifyItemRemoved(headers.size()+items.size()+footers.indexOf(footer));
footers.remove(footer);
if(footer.getParent() != null) {
((ViewGroup) footer.getParent()).removeView(footer);
}
}
}
//our header/footer RecyclerView.ViewHolder is just a FrameLayout
public static class HeaderFooterViewHolder extends RecyclerView.ViewHolder{
FrameLayout base;
public HeaderFooterViewHolder(View itemView) {
super(itemView);
this.base = (FrameLayout) itemView;
}
}
}
@appcoderavi
Copy link

What is GenericViewHolder in that code??
I'm trying to implement your code in my project after implementing error shown like error resolve symbol 'GenericViewHolder'

@dgngulcan
Copy link

@appcoderavi It is a class that used to hold your view basically.
It is a very useful pattern for performance improvements in your recyclerview for enhanced smoothness.
An example view holder class is bellow

public class ViewHolder extends RecyclerView.ViewHolder {
        public final View mView;
        public final TextView mainText;
        public final TextView secondaryText;
        public AnswerModel.Answer answer;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mainText = (TextView) view.findViewById(R.id.main_text);
            secondaryText = (TextView) view.findViewById(R.id.secondary_text);
        }
    }```

@HuyTranVan
Copy link

That is good solution

@anbu121
Copy link

anbu121 commented Nov 30, 2017

I have a Recycler view with Grid Layout. If I implement this code, would the header and footer too would be a grid item?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment