こんにちは。
こういう物は初めて書くので、勝手がわかりませんがよろしくお願いします。
あらすじ
AndroidアプリでListViewを使ってた
↓
CoordinatorLayoutを使いたい
↓
RecyclerView使おう
↓
ヘッダーとフッターがパッと付けれない
↓
ヘッダーとフッターを付けれるようにAdapter作った
↑
この時に作ったAdapterを今回ご紹介します。(GitHubに置いてみました。)
誰かのお役にたてればと。(もう既にあるのかな)
おかしいところあったらごめんなさい。
作ったAdapterの使い方
// 使いたいアダプタを作る
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);
動きを軽く解説
コンストラクタでメインで動くアダプタをもらいます。
基本こいつに横流しで動いてもらいます。
public PaneRecyclerViewAdapter(RecyclerView.Adapter adapter) {
mAdapter = adapter;
}
適当に種類を仕分けします。
@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;
}
アイテム数はヘッダーとフッターの個数を足して返します。
@Override
public int getItemCount() {
int extraCount = 0;
if(mHeaderView != null) extraCount += 1;
if(mFooterView != null) extraCount += 1;
return mAdapter.getItemCount() + extraCount;
}
普通のアイテムのViewHolderは貰ったAdapterに作らせます。
@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なので横流しの親まかせです。
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はやること無いから何もしないでいい、はず
@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使えば外でもできる、はず)
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;
}
おわり
難しいことはして無いはずです。
が、当時はヒイヒイ言いながら作ってました。
何かありましたら教えてください。
失礼します。
Github