前面一篇RecyclerView 通用Adapter添加头部、尾部 参考ListView的源码实现(一)文章中的实现的RecyclerBaseAdapter是有一些缺陷的,它只适用于头部、尾部ItemViewType类型为仅为一种。
后面稍微改进了一下,允许多ItemViewType,但是需要开发者保证头部View、尾部View、正常View的ItemViewType不重复,实际开发中类型也不会过多的。
示例源码:
public class ListViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
RecyclerView recyclerView = new RecyclerView(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
InnerAdapter innerAdapter = new InnerAdapter();
RecyclerBaseAdapter baseAdapter = new RecyclerBaseAdapter(innerAdapter);
baseAdapter.setHeaderAdapter(new HeaderAdapter());
baseAdapter.setFooterAdapter(new FooterAdapter());
recyclerView.setAdapter(baseAdapter);
addContentView(recyclerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
abstract class HeaderViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
/**
* 必须保证头部、尾部、正常部分的viewType类型不会重复
*/
protected SparseIntArray viewTypes=new SparseIntArray();
/**
* 判断viewType是否属于当前Adapter
* @param viewType
* @return
*/
public boolean isExistByViewType(int viewType){
return viewTypes.indexOfValue(viewType)!=-1;
}
}
class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(viewType==1){
return new HeadViewHoloder(LayoutInflater.from(ListViewActivity.this).inflate(android.R.layout.simple_list_item_1, null, false));
}else {
return new HeadViewHoloder(LayoutInflater.from(ListViewActivity.this).inflate(android.R.layout.simple_list_item_single_choice, null, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
HeadViewHoloder holoder_ = (HeadViewHoloder) holder;
((TextView) holoder_.itemView).setText("我是头部" + position+",ViewType"+getItemViewType(position));
}
@Override
public int getItemViewType(int position) {
int type= viewTypes.get(position,-1);
if(type==-1){
//写的参考测试类型
if(position%2==0){
type=1;
}else {
type=2;
}
viewTypes.put(position,type);
}
return type;
}
@Override
public int getItemCount() {
return 2;
}
class HeadViewHoloder extends RecyclerView.ViewHolder {
public HeadViewHoloder(View itemView) {
super(itemView);
}
}
}
class InnerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InnerViewHoloder(LayoutInflater.from(ListViewActivity.this).inflate(android.R.layout.simple_list_item_1, null, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
InnerViewHoloder holoder_ = (InnerViewHoloder) holder;
((TextView) holoder_.itemView).setText("我是正常Item" + position);
}
@Override
public int getItemCount() {
return 8;
}
class InnerViewHoloder extends RecyclerView.ViewHolder {
public InnerViewHoloder(View itemView) {
super(itemView);
}
}
}
class FooterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(viewType==3){
return new FooterViewHoloder(LayoutInflater.from(ListViewActivity.this).inflate(android.R.layout.simple_list_item_1, null, false));
}else {
return new FooterViewHoloder(LayoutInflater.from(ListViewActivity.this).inflate(android.R.layout.simple_list_item_single_choice, null, false));
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
FooterViewHoloder holoder_ = (FooterViewHoloder) holder;
((TextView) holoder_.itemView).setText("我是尾部" + position+",ViewType"+getItemViewType(position));
}
@Override
public int getItemViewType(int position) {
int type= viewTypes.get(position,-1);
if(type==-1){
//写的参考测试类型
if(position%2==0){
type=3;
}else {
type=4;
}
viewTypes.put(position,type);
}
return type;
}
@Override
public int getItemCount() {
return 3;
}
class FooterViewHoloder extends RecyclerView.ViewHolder {
public FooterViewHoloder(View itemView) {
super(itemView);
}
}
}
class RecyclerBaseAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private RecyclerView.Adapter mInnerAdapter;
private HeaderViewAdapter headerAdapter;
private HeaderViewAdapter footerAdapter;
public boolean isHasHeader() {
return headerAdapter != null;
}
public boolean isHasFooter() {
return footerAdapter != null;
}
public void setHeaderAdapter(HeaderViewAdapter hasHeader) {
this.headerAdapter = hasHeader;
}
public void setFooterAdapter(HeaderViewAdapter footerAdapter) {
this.footerAdapter = footerAdapter;
}
public RecyclerBaseAdapter(RecyclerView.Adapter mInnerAdapter) {
this.mInnerAdapter = mInnerAdapter;
}
private boolean isHeaderViewType(int position) {
return isHasHeader() && position <headerAdapter.getItemCount();
}
private boolean isFooterViewType(int position) {
return isHasFooter() && (getItemCount()- position <=footerAdapter.getItemCount());
}
private int getHeaderCount() {
return isHasHeader() ? headerAdapter.getItemCount() : 0;
}
private int getFooterCount() {
return isHasFooter() ? footerAdapter.getItemCount() : 0;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (isHasHeader() && headerAdapter.isExistByViewType(viewType)) {
return headerAdapter.onCreateViewHolder(parent, viewType);
} else if (isHasFooter() && footerAdapter.isExistByViewType(viewType)) {
return footerAdapter.onCreateViewHolder(parent, viewType);
} else {
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if(isHeaderViewType(position)){
headerAdapter.onBindViewHolder(holder, position);
}else if(isFooterViewType(position)){
footerAdapter.onBindViewHolder(holder, position - mInnerAdapter.getItemCount() - getHeaderCount());
}else {
mInnerAdapter.onBindViewHolder(holder, position - getHeaderCount());
}
}
@Override
public int getItemCount() {
return mInnerAdapter.getItemCount() + getHeaderCount() + getFooterCount();
}
@Override
public int getItemViewType(int position) {
if (isHeaderViewType(position)) {
return headerAdapter.getItemViewType(position);
} else if (isFooterViewType(position)) {
return footerAdapter.getItemViewType(position - mInnerAdapter.getItemCount() - getHeaderCount());
}
return mInnerAdapter.getItemViewType(position - getHeaderCount());
}
}
}