RecyclerView默认没有提供类似addHeaderView()
和addFooterView()
的API,因此这里介绍如何优雅地实现这两个接口。
如果你已经实现了一个Adapter,现在想为这个Adapter添加addHeaderView()
和addFooterView()
接口,则需要在Adapter中添加几个Item Type,然后修改getItemViewType()
,onCreateViewHolder()
,onBindViewHolder()
,getItemCount()
等方法,并添加switch语句进行判断。那么如何在不破坏原有Adapter实现的情况下完成呢?
这里引入装饰器(Decorator)设计模式,该设计模式通过组合的方式,在不破话原有类代码的情况下,对原有类的功能进行扩展。
具体实现思路其实很简单,创建一个继承RecyclerView.Adapter<RecyclerView.ViewHolder>
的类,并重写常见的方法,然后通过引入ITEM TYPE的方式实现:
public class NormalAdapterWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
enum ITEM_TYPE{
HEADER,
FOOTER,
NORMAL
}
private NormalAdapter mAdapter;
private View mHeaderView;
private View mFooterView;
public NormalAdapterWrapper(NormalAdapter adapter){
mAdapter = adapter;
}
@Override
public int getItemViewType(int position) {
if(position == 0){
return ITEM_TYPE.HEADER.ordinal();
} else if(position == mAdapter.getItemCount() + 1){
return ITEM_TYPE.FOOTER.ordinal();
} else{
return ITEM_TYPE.NORMAL.ordinal();
}
}
@Override
public int getItemCount() {
return mAdapter.getItemCount() + 2;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(position == 0){
return;
} else if(position == mAdapter.getItemCount() + 1){
return;
} else{
mAdapter.onBindViewHolder(((NormalAdapter.VH)holder), position - 1);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == ITEM_TYPE.HEADER.ordinal()){
return new RecyclerView.ViewHolder(mHeaderView) {};
} else if(viewType == ITEM_TYPE.FOOTER.ordinal()){
return new RecyclerView.ViewHolder(mFooterView) {};
} else{
return mAdapter.onCreateViewHolder(parent,viewType);
}
}
public void addHeaderView(View view){
this.mHeaderView = view;
}
public void addFooterView(View view){
this.mFooterView = view;
}
}
这恰恰满足了我们的需求。我们只需要通过以下方式为原有的Adapter(这里命名为NormalAdapter)添加addHeaderView()
和addFooterView()
接口:
NormalAdapter adapter = new NormalAdapter(data);
NormalAdapterWrapper newAdapter = new NormalAdapterWrapper(adapter);
View headerView = LayoutInflater.from(this).inflate(R.layout.item_header, mRecyclerView, false);
View footerView = LayoutInflater.from(this).inflate(R.layout.item_footer, mRecyclerView, false);
newAdapter.addFooterView(footerView);
newAdapter.addHeaderView(headerView);
mRecyclerView.setAdapter(newAdapter);
是不是看起来特别优雅。