RecyclerViewにヘッダーとフッターを付けたかった時に作った物のご紹介

こんにちは。
こういう物は初めて書くので、勝手がわかりませんがよろしくお願いします。

# あらすじ
AndroidアプリでListViewを使ってた
↓
CoordinatorLayoutを使いたい
↓
RecyclerView使おう
↓
ヘッダーとフッターがパッと付けれない
↓
ヘッダーとフッターを付けれるようにAdapter作った
↑
この時に作ったAdapterを今回ご紹介します。（[GitHubに置いてみました。](https://github.com/syuki/PaneRecyclerViewAdapter)）
誰かのお役にたてればと。（もう既にあるのかな）
おかしいところあったらごめんなさい。:bow_tone1:
<img width="300" src="https://qiita-image-store.s3.amazonaws.com/0/178781/5cc3f82f-a548-994c-172a-3df5500d7c8c.png"> <img width="300" src="https://qiita-image-store.s3.amazonaws.com/0/178781/873dd156-5e59-4fa7-4878-575546318c88.png">

# 作ったAdapterの使い方
```java
// 使いたいアダプタを作る
MyAdapter adapter = new MyAdapter();

// PaneRecyclerViewAdapter作る
PaneRecyclerViewAdapter paneRecyclerViewAdapter = new PaneRecyclerViewAdapter(adapter); // アダプタあげる

// GridViewならLayoutManagerあげる
//paneRecyclerViewAdapter.setGridLayoutManager(gridLayoutManager);

// ヘッダーとフッターのビューをあげる
paneRecyclerViewAdapter.setHeaderView(headerView);
paneRecyclerViewAdapter.setFooterView(footerView);

// RecyclerViewにPaneRecyclerVieAdapterをあげる
recyclerView.setAdapter(paneRecyclerViewAdapter);
```
# 動きを軽く解説
コンストラクタでメインで動くアダプタをもらいます。
基本こいつに横流しで動いてもらいます。

```java
public PaneRecyclerViewAdapter(RecyclerView.Adapter adapter) {
    mAdapter = adapter;
}
```
適当に種類を仕分けします。

```java
@Override
public int getItemViewType(int position) {
    if(isHeader(position)) {
        return ITEM_VIEW_TYPE_HEADER;
    }
    if(isFooter(position)) {
        return ITEM_VIEW_TYPE_FOOTER;
    }

    return ITEM_VIEW_TYPE_ITEM;
}

private boolean isHeader(int position) {
    return mHeaderView != null && position == 0;
}

private boolean isFooter(int position) {
    int extraCount = mHeaderView != null ? 1 : 0;
    return mFooterView != null && position == mAdapter.getItemCount() + extraCount;
}
```
アイテム数はヘッダーとフッターの個数を足して返します。

```java
@Override
public int getItemCount() {
    int extraCount = 0;
    if(mHeaderView != null) extraCount += 1;
    if(mFooterView != null) extraCount += 1;
    return mAdapter.getItemCount() + extraCount;
}
```
普通のアイテムのViewHolderは貰ったAdapterに作らせます。

```java
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if(viewType == ITEM_VIEW_TYPE_HEADER) {
        return new ViewHolder(mHeaderView);
    }

    if(viewType == ITEM_VIEW_TYPE_FOOTER) {
        return new ViewHolder(mFooterView);
    }

    RecyclerView.ViewHolder viewHolder = mAdapter.onCreateViewHolder(parent, viewType);
    return new ViewHolder(viewHolder);
}
```

ちなみに、PaneRecyclerのViewHolderは以下の感じです。
普通アイテムは生のViewHolder型でとっておいて、必要になったら渡します。
HeaderやFooterは既にViewなので横流しの親まかせです。

```java
static class ViewHolder extends RecyclerView.ViewHolder {
    private RecyclerView.ViewHolder mItemViewHolder;

    ViewHolder(View itemView) {
        super(itemView);
    }

    ViewHolder(RecyclerView.ViewHolder viewHolder) {
        super(viewHolder.itemView);
        mItemViewHolder = viewHolder;
    }

    RecyclerView.ViewHolder getItemViewHolder() {
        return mItemViewHolder;
    }
}
```
onBindも普通のアイテムはもらったAdapter任せです。
HeaderFooterはやること無いから何もしないでいい、はず

```java
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    if(isHeader(position)) return;
    if(isFooter(position)) return;
    int extraCount = mHeaderView != null ? 1 : 0;
    mAdapter.onBindViewHolder(holder.getItemViewHolder(), position - extraCount);
}
```
GridLayoutの時に、HeaderFooterは横いっぱいに居て欲しいので、SpanSizeLookup？で設定するみたいです。
Linearはみんな横いっぱいなので何もしなくても良いっぽいです。
簡単に設定できるようにと中でやってますが、外で設定したい場合はそうしてもらっても大丈夫です。（下に用意したgetSpanSize使えば外でもできる、はず）

```java
public void setGridLayoutManager(GridLayoutManager gridLayoutManager) {
    mSpanCount = gridLayoutManager.getSpanCount();
    gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            return PaneRecyclerViewAdapter.this.getSpanSize(position);
        }
    });
}
public int getSpanSize(int position) {
    if(isHeader(position) || isFooter(position)) {
        return mSpanCount;
    }
    return 1;
}
```

# おわり
難しいことはして無いはずです。
が、当時はヒイヒイ言いながら作ってました。
何かありましたら教えてください。
失礼します。:walking_tone1:

#Github
https://github.com/syuki/PaneRecyclerViewAdapter