福利:打造一个万能的RecyclerViewAdapter

由于本鸟在之前确实没有用到过RecyclerView,正好今天比较闲,所以干脆找点资料,学习了一下这个神奇的控件。

特点:RecyclerView可以实现线性布局(横向线性布局和纵向线性布局),网格布局(有了这个,基本上可以抛弃GridView了),还可以实现瀑布流,就是那种很炫的效果,这种布局目前来说还是比较流行的。

使用起来跟ListView差不多吧,无非就是在资源文件中定义这个控件,给它一个id,然后到代码里通过findViewById()找到它,然后设置一系列参数,最后通过setAdapter给它一组数据,显示到界面上就ok了,这篇文章主要研究Adapter,其他的暂且搁在一边。

我们需要继承RecyclerView.Adapter这个类,来实现我们自己的Adapter,看代码

public class NormalAdapter extends RecyclerView.Adapter {
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //这里返回一个Holder,在ListView中我们也会使用ViewHolder来减少findViewById()的次数,提高listview效率
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //这里主要进行一些View的,比如给按钮设置个点击监听器,或者给TextView设置文字,或者给ImageView设置src,懂了吧,反正就是初始化

    }
    
    @Override
    public int getItemCount() {
        //返回数据集的长度
        return 0;
    }
}

 刚开始如果我们什么都不做,那代码就是这样的,必须要override三个方法,看上面的代码就知道了,ViewHolder暂时 先别管,不懂得同学,你就理解成ListView中的Holder好了,都是一样的。


好了,废话不多说,我问一个问题,你们仔细看,这个NormalAdapter的代码量多不多?(请思考5分钟)

........................

好了,思考时间结束。觉得代码量不多的人,可以把电脑关掉,洗洗睡了。。。觉得代码量多的人,可以自行往下阅读,我教你如何打造一款万能的Adapter,只要写一个Adapter,就可以“到处”运行微笑微笑微笑

设想一下,一个项目中,我们如果要写几十个Adapter,每个Adapter都要这么重复来重复去的,事件浪费掉了不去说,家里老婆孩子还等着你回家做饭吃呢,而且,如果代码出问题了,你还要一个个Adapter去看,到底是哪个Adapter出问题了,能把你搞死,我反正要被搞死了。。。。。所以写了这篇博客,希望能够帮到大家


既然这三个方法是一定要重写的,那为毛我们不定义一个BaseAdpter类呢,然后让所有的Adapter来继承这个BaseAdapter类,省去了多余的代码,下面看我是怎么定义这个BaseAdapter的,看代码:

public abstract class BaseAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter {

    private static final String TAG = "BaseAdapter";
    private static final int HEADER_VIEW = 0x1001;
    private static final int FOOTER_VIEW = 0x1002;

    private View headerView;
    private View footerView;

    @Override
    public int getItemViewType(int position) {
        if (position == 0 && hasHeaderView()) {
            return HEADER_VIEW;
        }
        if (position == getItemCount() - 1 && hasFooterView()) {
            return FOOTER_VIEW;
        }
        //如果既不是头部View,也不是尾部View,那就让用户去判断,该View到底是什么type
        return getViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == HEADER_VIEW) {
            return new EmptyViewHolder(headerView);
        }
        if (viewType == FOOTER_VIEW) {
            return new EmptyViewHolder(footerView);
        }
        return onCreateHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int type = getItemViewType(position);
        if (type == HEADER_VIEW) {
            return;
        }
        if (type == FOOTER_VIEW) {
            return;
        }
        onBindHolder((VH) holder, position);
    }

    public void addHeaderView(View headerView) {
        this.headerView = headerView;
    }

    public void removeHeaderView() {
        this.headerView = null;
    }

    public void addFooterView(View footerView) {
        this.footerView = footerView;
    }

    public void removeFooterView() {
        this.footerView = null;
    }

    public boolean hasHeaderView() {
        return headerView == null ? false : true;
    }

    public boolean hasFooterView() {
        return footerView == null ? false : true;
    }

    //如果用户不指定,默认的类型就是0
    public int getViewType(int position) {
        return 0;
    }

    abstract VH onCreateHolder(ViewGroup parent, int viewType);

    abstract void onBindHolder(VH holder, int position);
}

为了方便,我就直接把所有代码贴上来了,来,听我慢慢道来~~~


我这个BaseAdapter是可以添加Header和Footer的,用到了泛型和抽象类,看不懂的没关系,就当泛型不存在就好了,自己脑子里把泛型替换成一个具体的类就好了

先说一下执行顺序吧,getItemViewTyoe先执行,然后返回一个type,然后去执行onCreateViewHolder,这个方法会根据传过来的type来初始化相应的Holder

打个比方,如果传过来的type是HEADER_VIEW,就会去实例化EmptyViewHolder,如果传过来的type是美女,那就会去实例化BeautyHolder,虽然我们这里没有美女Holder。BeautyHolder里面有一些属性,比如年龄,身高,体重,三围,爱好,婚否什么的,都会在这个时候初始化,注意,这一步只是用来确定某个Holder有哪些属性,并不会给属性值赋予初始化,用代码就是就是这一步只是进行了findViewById操作,其他操作都不会进行。初始化之后会把这个BeautyHolder传给onBindViewHolder这个方法,这个方法干什么的呢,这个方法就是初始化这些属性的值得,比如三围是25,65,25,体重是80KG,爱好是刮腿毛什么的,都初始化好之后,整个View也就呈现在我们的界面上了。。。


Header表示整个Adapter的头部View,Footer表示整个Adapter的底部View,可以添加,也可以删除


我再解释一下那几个抽象方法,onCreateHolder是这么滴,假如某个View的类型既不是header,也不是footer,那我们的onCreateHolder就不知道到底该初始化哪个Holder了,于是就写了一个抽象的方法,交给子类去实现,具体是哪个Holder,这个依据业务逻辑定,这么写的话比较灵活的

onBindHolder方法也是,当BaseAdapter不知道怎么办的时候,就让子类去做


具体使用的话只要复制这个BaseAdapter类,然后让其他类继承这个类就好了,以后我会慢慢完善这个类,让它拥有更多的功能。主要还是为了方便开发吧

代码的话还是要好好琢磨的,毕竟里面有几个抽象方法,还使用到了泛型,我自己写出来感觉没啥,能看懂,但你们看可能有点绕。

希望持续关注我的博客,有不懂得可以在下方留言,我会尽力帮助你,源代码和相应的demo会在后期更新,想要的同学可以留意一下。

天天加班,也是没谁了。公司里的人都走光了,就剩我了,写完这篇博客,上传之后我要赶紧回家睡觉了,十一快到了,预祝大家国庆节快乐~~~~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值