装饰模式是一种用来替代继承的思想,它使用对象之间的关联关系来取代类之间的继承关系。继承是一种常用的一种拓展原有类的功能的方法,通过创建一个继承父类的子类来拓展原有的功能,在“合成复用原则”中曾提到,在处理类的功能拓展这个问题上应尽量使用类之间的关联关系而少使用继承关系。
RecyclerView 本身是不支持添加底部和头部的,那么采用装饰设计模式可以对其进行功能扩展,使其能够支持底部和头部的添加: public class WrapRecyclyerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { //包装原来的RecyclyerView.Adapter private RecyclerView.Adapter mAdapter; List<View> mHeadViews;//头部 List<View> mFooterViews;//底部 public WrapRecyclyerAdapter(RecyclerView.Adapter adapter) { mAdapter = adapter; mHeadViews = new ArrayList<>(); mFooterViews = new ArrayList<>(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) { int headersCount = getHeadersCount(); if (position < headersCount) { return createFooterHeaderViewHolder(mHeadViews.get(position)); } int adjPosition = position - headersCount; int adapterCount = 0; if (mAdapter != null) { adapterCount = mAdapter.getItemCount(); if (adjPosition < adapterCount) { return mAdapter.onCreateViewHolder(parent, mAdapter.getItemViewType(adjPosition)); } } return createFooterHeaderViewHolder(mFooterViews.get(adjPosition - adapterCount)); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { int headersCount = getHeadersCount(); if (position < headersCount) { return; } int adjPosition = position - headersCount; if (mAdapter != null) { int itemCount = mAdapter.getItemCount(); if (adjPosition < itemCount) { mAdapter.onBindViewHolder(holder, adjPosition); } } } @Override public int getItemCount() { return mAdapter.getItemCount() + mHeadViews.size() + mFooterViews.size(); } @Override public int getItemViewType(int position) { return position; } public int getHeadersCount() { return mHeadViews.size(); } private RecyclerView.ViewHolder createFooterHeaderViewHolder(View view) { return new RecyclerView.ViewHolder(view) { }; } /** * 添加底部view * * @param view */ public void addFootView(View view) { if (!mFooterViews.contains(view)) { mFooterViews.add(view); notifyDataSetChanged(); } } /** * 添加头部view * * @param view */ public void addHeaderView(View view) { if (!mHeadViews.contains(view)) { mHeadViews.add(view); notifyDataSetChanged(); } } public void removeHeaderView(View view) { if (mHeadViews.contains(view)) { mHeadViews.remove(view); notifyDataSetChanged(); } } public void removeFootView(View view) { if (mFooterViews.contains(view)) { mFooterViews.remove(view); notifyDataSetChanged(); } } } public class WrapRecyclerView extends RecyclerView { // 支持添加头部和底部的 RecyclerView.Adapter private WrapRecyclyerAdapter mWrapRecyclyerAdapter; public WrapRecyclerView(Context context) { super(context); } public WrapRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public WrapRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setAdapter(Adapter adapter) { mWrapRecyclyerAdapter = new WrapRecyclyerAdapter(adapter); super.setAdapter(mWrapRecyclyerAdapter); } public void addHeaderView(View view) { if (mWrapRecyclyerAdapter != null) { mWrapRecyclyerAdapter.addHeaderView(view); } } /** * 添加底部View * * @param view */ public void addFooterView(View view) { if (mWrapRecyclyerAdapter != null) { mWrapRecyclyerAdapter.addFootView(view); } } /** * 移除头部View * * @param view */ public void removeHeaderView(View view) { if (mWrapRecyclyerAdapter != null) { mWrapRecyclyerAdapter.removeHeaderView(view); } } /** * 移除底部View * * @param view */ public void removeFooterView(View view) { if (mWrapRecyclyerAdapter != null) { mWrapRecyclyerAdapter.removeFootView(view); } } }