实现加载头部和顶部布局的BaseAdapter

首先判断当前加载哪种布局,重写getItemViewType方法

        if (position == 0) {
            if (head_layout_id != 0) {
                return TYPE_HEAD;
            } else {
                return TYPE_NULL;
            }
        }
        if (position + 1 == getItemCount()) {
            if (foot_layout_id != 0) {
                return TYPE_FOOT;
            } else {
                return TYPE_NULL;
            }
        }
        return TYPE_NORMAL;

在onCreateViewHolder中根据不同的viewType加载不同的布局,最好确保返回值不为空,不然可能会抛出异常

   @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_HEAD:
                headView = inflater.inflate(head_layout_id, parent, false);
                return createHeadView(parent, viewType);
            case TYPE_NORMAL:
                itemView = inflater.inflate(normal_layout_id, parent, false);
                return createItemView(parent, viewType);
            case TYPE_FOOT:
                footView = inflater.inflate(foot_layout_id, parent, false);
                return createFootView(parent, viewType);
            default:
                return new BaseViewHolder(new View(context));
        }
    }

在onBindViewHolder中根据不同viewType绑定不同数据

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        if (position == 0) {
            if (head_layout_id != 0) bindHeadView((HEAD) holder, 0);
        } else if (position + 1 == getItemCount()) {
            if (foot_layout_id != 0) bindFootView((FOOT) holder, position);
        } else {
            bindItemView((ITEM) holder, position);
        }
    }

子类中需重写的方法

    protected abstract ITEM createItemView(ViewGroup parent, int viewType);

    protected abstract HEAD createHeadView(ViewGroup parent, int viewType);

    protected abstract FOOT createFOOTView(ViewGroup parent, int viewType);
    protected abstract void bindItemView(ITEM holder, int position);

    protected abstract void bindHeadView(HEAD holder, int position);

    protected abstract void bindFootView(FOOT holder, int position);

最后是完整的代码
BaseAdapter

public abstract class BaseAdapter<HEAD extends BaseViewHolder, ITEM extends BaseViewHolder, FOOT extends BaseViewHolder, DATA> extends RecyclerView.Adapter<BaseViewHolder> {
    private final int TYPE_HEAD = 1;
    private final int TYPE_NORMAL = 2;
    private final int TYPE_FOOT = 3;
    private final int TYPE_NULL = 4;

    protected Context context;
    protected LayoutInflater inflater;
    protected int normal_layout_id;
    protected int head_layout_id;
    protected int foot_layout_id;
    protected List<DATA> dataList;
    protected View headView;
    protected View itemView;
    protected View footView;
    protected OnLoadMoreListener onLoadMoreListener;

    public BaseAdapter(Context context, int head_layout_id, int layout_id, int foot_layout_id, List<DATA> dataList) {
        this.context = context;
        this.foot_layout_id = foot_layout_id;
        this.head_layout_id = head_layout_id;
        this.normal_layout_id = layout_id;
        this.dataList = dataList;
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_HEAD:
                headView = inflater.inflate(head_layout_id, parent, false);
                return createHeadView(parent, viewType);
            case TYPE_NORMAL:
                itemView = inflater.inflate(normal_layout_id, parent, false);
                return createItemView(parent, viewType);
            case TYPE_FOOT:
                footView = inflater.inflate(foot_layout_id, parent, false);
                return createFootView(parent, viewType);
            default:
                return new BaseViewHolder(new View(context));
        }
    }

    protected abstract ITEM createItemView(ViewGroup parent, int viewType);

    protected abstract HEAD createHeadView(ViewGroup parent, int viewType);

    protected abstract FOOT createFootView(ViewGroup parent, int viewType);

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        if (position == 0) {
            if (head_layout_id != 0) bindHeadView((HEAD) holder, 0);
        } else if (position + 1 == getItemCount()) {
            if (foot_layout_id != 0) bindFootView((FOOT) holder, position);
        } else {
            bindItemView((ITEM) holder, dataList.get(position - 1));
        }
    }

    protected abstract void bindItemView(ITEM holder, DATA data);

    protected abstract void bindHeadView(HEAD holder, int position);

    protected abstract void bindFootView(FOOT holder, int position);

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            if (head_layout_id != 0) {
                return TYPE_HEAD;
            } else {
                return TYPE_NULL;
            }
        }
        if (position + 1 == getItemCount()) {
            if (foot_layout_id != 0) {
                return TYPE_FOOT;
            } else {
                return TYPE_NULL;
            }
        }
        return TYPE_NORMAL;
    }

    @Override
    public int getItemCount() {
        return dataList.size() + 2;
    }

    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        this.onLoadMoreListener = onLoadMoreListener;
    }

    public void clearData() {
        if (dataList != null) dataList.clear();
    }

    public void addData(List<DATA> moreList) {
        dataList.addAll(moreList);
    }

    //可手动添加一个加载更多失败的回调
    public interface OnLoadMoreListener {
        void loadMore(BaseViewHolder footHolder);
    }
}

BaseViewHolder

public class BaseViewHolder extends RecyclerView.ViewHolder {
    public BaseViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

DATA为需要绑定的数据类型

使用
依次传入头部,正常item,底部布局的ViewHolder还有实现数据绑定的数据类型

public class DemoAdapter extends BaseAdapter<HeadViewHolder,AdviceViewHolder,FootViewHolder,DesignAdvice>{

    public DemoAdapter(Context context, int foot_layout_id, int head_layout_id, int layout_id, List<DesignAdvice> designAdvices) {
        super(context, foot_layout_id, head_layout_id, layout_id, designAdvices);
    }

    @Override
    protected AdviceViewHolder createItemView(ViewGroup parent, int viewType) {
        return new AdviceViewHolder(itemView);
    }

    @Override
    protected HeadViewHolder createHeadView(ViewGroup parent, int viewType) {
        return new HeadViewHolder(headView);
    }

    @Override
    protected FootViewHolder createFootView(ViewGroup parent, int viewType) {
        return new FootViewHolder(footView);
    }

    @Override
    protected void bindItemView(AdviceViewHolder holder, DesignAdvice designAdvice) {
    //操作数据
        holder.title.setText(designAdvice.getTitle());
        holder.itemView.setTag(designAdvice);
    }

    @Override
    protected void bindHeadView(HeadViewHolder holder, int position) {

    }

    @Override
    protected void bindFootView(FootViewHolder holder, int position) {

    }
}

有时候我们并不需要头部和底部的布局,但直接继承这个BaseAdapter还是会有些多余的代码,所以我决定进一步封装一个只有正常item的adapter

DataAdapter

public abstract class DataAdapter<ITEM extends BaseViewHolder, DATA> extends BaseAdapter<BaseViewHolder, ITEM, BaseViewHolder, DATA> {

    public DataAdapter(Context context, int layout_id, List<DATA> datas) {
        super(context, 0, layout_id, 0, datas);
    }

    @Override
    protected BaseViewHolder createHeadView(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    protected BaseViewHolder createFootView(ViewGroup parent, int viewType) {
        return null;
    }


    @Override
    protected void bindHeadView(BaseViewHolder holder, int position) {
    }

    @Override
    protected void bindFootView(BaseViewHolder holder, int position) {
    }
}

代码也很简单,继承BaseAdapter,顶部和底部的布局id传入0即可,然后重写他们的createView和bindView方法。

使用

public class DemoAdapter extends DataAdapter<AdviceViewHolder, DesignAdvice> {
    public DemoAdapter(Context context, int layout_id, List<DesignAdvice> designAdvices) {
        super(context, layout_id, designAdvices);
    }

    @Override
    protected AdviceViewHolder createItemView(ViewGroup parent, int viewType) {
        return new AdviceViewHolder(itemView);
    }

    @Override
    protected void bindItemView(AdviceViewHolder holder, DesignAdvice designAdvice) {
        holder.title.setText(designAdvice.getTitle());
        holder.itemView.setTag(designAdvice);
    }
}

直接传入布局的ViewHolder和需要处理的数据。我们只要把精力放在bindView中数据的显示即可了。需要写的代码基本只在bindView中了。也不用再去频繁的根据position获取List中的数据了,这些工作都已经封装好了。


类似的还可以封装有head和item的adapter以及有foot和item的adapter。要是三种都需要就使用BaseAdapter。


有底部布局和item的Adapter

public abstract class DataWFootAdapter<ITEM extends BaseViewHolder, FOOT extends BaseViewHolder, DATA> extends BaseAdapter<BaseViewHolder, ITEM, FOOT, DATA> {
    public DataWFootAdapter(Context context,  int layout_id, int foot_layout_id, List<DATA> datas) {
        super(context,0, layout_id, foot_layout_id, datas);
    }

    @Override
    protected BaseViewHolder createHeadView(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    protected void bindHeadView(BaseViewHolder holder, int position) {
    }
}

有头部布局的Adapter

public abstract class DataWHeadAdapter<HEAD extends BaseViewHolder,ITEM extends BaseViewHolder, DATA> extends BaseAdapter<HEAD, ITEM, BaseViewHolder, DATA>{
    public DataWHeadAdapter(Context context, int head_layout_id, int layout_id, int foot_layout_id, List<DATA> datas) {
        super(context, head_layout_id, layout_id, foot_layout_id, datas);
    }

    @Override
    protected BaseViewHolder createFootView(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    protected void bindFootView(BaseViewHolder holder, int position) {
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值