Skip to content

Instantly share code, notes, and snippets.

@sebnapi
Last active July 31, 2025 16:37
Show Gist options
  • Select an option

  • Save sebnapi/fde648c17616d9d3bcde to your computer and use it in GitHub Desktop.

Select an option

Save sebnapi/fde648c17616d9d3bcde to your computer and use it in GitHub Desktop.

Revisions

  1. sebnapi revised this gist Nov 8, 2014. 1 changed file with 16 additions and 0 deletions.
    16 changes: 16 additions & 0 deletions HeaderRecyclerViewAdapterV2.java
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,19 @@
    /*
    * Copyright (C) 2014 sebnapi
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    import android.support.v7.widget.RecyclerView;
    import android.view.ViewGroup;

  2. sebnapi created this gist Nov 8, 2014.
    102 changes: 102 additions & 0 deletions HeaderRecyclerViewAdapterV2.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    import android.support.v7.widget.RecyclerView;
    import android.view.ViewGroup;

    /**
    * Created by sebnapi on 08.11.14.
    * <p/>
    * If you extend this Adapter you are able to add a Header, a Footer or both
    * by a similar ViewHolder pattern as in RecyclerView.
    * <p/>
    * If you want to omit changes to your class hierarchy you can try the Plug-and-Play
    * approach HeaderRecyclerViewAdapterV1.
    * <p/>
    * Don't override (Be careful while overriding)
    * - onCreateViewHolder
    * - onBindViewHolder
    * - getItemCount
    * - getItemViewType
    * <p/>
    * You need to override the abstract methods introduced by this class. This class
    * is not using generics as RecyclerView.Adapter make yourself sure to cast right.
    * <p/>
    * TOTALLY UNTESTED - USE WITH CARE - HAVE FUN :)
    */
    public abstract class HeaderRecyclerViewAdapterV2 extends RecyclerView.Adapter {
    private static final int TYPE_HEADER = Integer.MIN_VALUE;
    private static final int TYPE_FOOTER = Integer.MIN_VALUE + 1;
    private static final int TYPE_ADAPTEE_OFFSET = 2;

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == TYPE_HEADER) {
    return onCreateHeaderViewHolder(parent, viewType);
    } else if (viewType == TYPE_FOOTER) {
    return onCreateFooterViewHolder(parent, viewType);
    }
    return onCreateBasicItemViewHolder(parent, viewType - TYPE_ADAPTEE_OFFSET);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (position == 0 && holder.getItemViewType() == TYPE_HEADER) {
    onBindHeaderView(holder, position);
    } else if (position == getBasicItemCount() && holder.getItemViewType() == TYPE_FOOTER) {
    onBindFooterView(holder, position);
    } else {
    onBindBasicItemView(holder, position - (useHeader() ? 1 : 0));
    }
    }

    @Override
    public int getItemCount() {
    int itemCount = getBasicItemCount();
    if (useHeader()) {
    itemCount += 1;
    }
    if (useFooter()) {
    itemCount += 1;
    }
    return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
    if (position == 0 && useHeader()) {
    return TYPE_HEADER;
    }
    if (position == getBasicItemCount() && useFooter()) {
    return TYPE_FOOTER;
    }
    if (getBasicItemType(position) >= Integer.MAX_VALUE - TYPE_ADAPTEE_OFFSET) {
    new IllegalStateException("HeaderRecyclerViewAdapter offsets your BasicItemType by " + TYPE_ADAPTEE_OFFSET + ".");
    }
    return getBasicItemType(position) + TYPE_ADAPTEE_OFFSET;
    }

    public abstract boolean useHeader();

    public abstract RecyclerView.ViewHolder onCreateHeaderViewHolder(ViewGroup parent, int viewType);

    public abstract void onBindHeaderView(RecyclerView.ViewHolder holder, int position);

    public abstract boolean useFooter();

    public abstract RecyclerView.ViewHolder onCreateFooterViewHolder(ViewGroup parent, int viewType);

    public abstract void onBindFooterView(RecyclerView.ViewHolder holder, int position);

    public abstract RecyclerView.ViewHolder onCreateBasicItemViewHolder(ViewGroup parent, int viewType);

    public abstract void onBindBasicItemView(RecyclerView.ViewHolder holder, int position);

    public abstract int getBasicItemCount();

    /**
    * make sure you don't use [Integer.MAX_VALUE-1, Integer.MAX_VALUE] as BasicItemViewType
    *
    * @param position
    * @return
    */
    public abstract int getBasicItemType(int position);

    }