recyclerview万能适配器。

2018-08-24  本文已影响0人  冬冬269

不做任何封装的情况下。每一个adapter中数据都不同,都要判断viewtype。onCreateViewHolder中都要根据不同的viewtype创建不同的viewholder,并且在bindviewholder中分别进行绑定。

个人分析:最后会贴代码
看了鸿洋大神的博客。首先对viewholder做了封装,将所有viewholder用一个统一的自定义viewholder来表示,因为不知道具体layout中view的数量。所以view存储到sparseArray中,去存取。所有的viewholder,唯一不同的是创建时使用的layout。

其实每一个不同类型的item,他们只有两处不同,一处是layout,一处是具体对layout的操作,对应到recyclerAdapter。就是OnCreatViewHolder,和bindViewHolder。所以我们把这两个不同抽象出来,给每一个不同的item去实现。仔细想想还有一处不同,就是我怎么知道这个item显示在哪里呢。是第一行还是最后一行等等。所以我们还要抽取出一个方法,用来判断他的viewType。

关于adapter中的getViewType。这是判断item究竟显示在哪里,或者说,这个item应该怎么显示。他提供了一个重要的参数,position。在这里,我们可以拿到JavaBean,然后再判断这里应该怎么显示,创建什么viewholder。在onCreateViewHolder中只有两个参数 view Group partent,int viewType。

请看代码。。思路参考鸿洋大神。viewholder还可以写辅助方法,设置Text,iamge,点击时间等。其中的难点是

 boolean isViewType(T obj,int position);

这里判断type。每一个不同的recyclerview中,也许判断不同。为了通用,这里得处理好。

public class ItemDelegateManager<T> {

    /**
     * 一个recyclerview,有不同的item。具体哪个position展现哪个item又manger来控制。
     * 将key值,作为viewType。可以指定key值。
     */
    /**
     * 存储着这个dapter所有的item代表。
     */
    private SparseArray<ItemDelegate> itemArrays;
    private Context mContext;

    public ItemDelegateManager(Context context){
        itemArrays = new SparseArray<>();
        mContext = context;
    }
    //判断返回哪个viewtype 根据postion和data。
    public int getViewType(int position,T data){

        //固定格式 如果为0 直接返回这种viewType。

        //可以按照他的key做viewtype
        int size = itemArrays.size();
        for (int i = 0;i<size;i++){
            ItemDelegate itemDelegate = itemArrays.valueAt(i);//根据角标拿到value。
            if(itemDelegate.isViewType(data,position)){
                return itemArrays.keyAt(i);//根据角标拿到key。
            }
        }
        return 1;
    }

    public int getLayout(int viewType){
        return itemArrays.get(viewType).getLayoutId();
    }

    public void conver(MyViewHolderWan holder, int position,T data) {
        // 这里调用itemDelegate的conver方法。根据data调用不同的itemDelegate。

        int size = itemArrays.size();
        for (int i = 0;i<size;i++){
            ItemDelegate itemDelegate = itemArrays.valueAt(i);//根据角标拿到value。
            if(itemDelegate.isViewType(data,position)){

                itemDelegate.conver(holder,position,data,mContext);
            }
        }

    }
    //添加itemdelegate 以长度做key
    public <T> void add(ItemDelegate<T> itemDelegate) {

        itemArrays.put(itemArrays.size(),itemDelegate);
    }
    //指定key
    public<T> void add(int key,ItemDelegate<T> itemDelegate){
        itemArrays.put(key,itemDelegate);
    }
}
public  class MyRecyclerAdapter<T> extends RecyclerView.Adapter<MyViewHolderWan> {

    //管理item。
    private ItemDelegateManager delegateManager;
    //数据集合。
    private List<T> datas;
    private Context context;

    public MyRecyclerAdapter(List<T> datas,Context context){
        delegateManager = new ItemDelegateManager(context);
        this.datas = datas;
    }

    @Override
    public MyViewHolderWan onCreateViewHolder(ViewGroup parent, int viewType) {
        //我们需要判断需要哪个layoutId
        //我们在这个方法中,没办法判断是第几个item的创建,所以拿不到javabean。
        //根据viewType来判断。
        int layout = delegateManager.getLayout(viewType);
        MyViewHolderWan myViewHolderWan = MyViewHolderWan.get(parent.getContext(),layout, parent);
        return myViewHolderWan;
    }

    @Override
    public void onBindViewHolder(MyViewHolderWan holder, int position) {
        conver(holder,position);
    }



    public  void conver(MyViewHolderWan holder, int position){
        //通过manager管理
        delegateManager.conver(holder,position,datas.get(position));
    };
    @Override
    public int getItemCount() {
        return datas.size();
    }


    //getItemViewType中最重要的参数是position。
    //我们知道我们要创建viewholder,需要根据不同的item来创建不同的viewholder。
    //postion我们可以判断位置,从来创建viewholder。

    @Override
    public int getItemViewType(int position) {
        return delegateManager.getViewType(position,datas.get(position));
    }

    //定义为抽象类。因为这个方法必须实现。不然没有item。
    public  void addItemDelegate(ItemDelegate<T> itemDelegate){
        delegateManager.add(itemDelegate);

    };
    public  void addItemDelegate(int type,ItemDelegate<T> itemDelegate){
        delegateManager.add(type,itemDelegate);

    };
}

public interface ItemDelegate<T> {

    /**
     * 每个item三个独特点。第一,layout。第二,conver。第三,isViewType。
     * @return
     */
    int getLayoutId();
    //十分重要。判断item要显示的是什么。
    boolean isViewType(T obj,int position);
    void conver(MyViewHolderWan holder,int position,T data,Context context);
}

public class LeftPictureItem implements ItemDelegate<TipOffBeans> {


    @Override
    public int getLayoutId() {
        return R.layout.recycler_item_news_leftpic;
    }

    @Override
    public boolean isViewType(TipOffBeans obj, int position) {
        if(position!= 0 &&!TextUtils.isEmpty(obj.imageurl)){
            //不为null 那就是有图片
            return true;
        }
        return false;
    }

    @Override
    public void conver(MyViewHolderWan holder, int position, TipOffBeans data, Context context) {
        ImageView pic = holder.getView(R.id.iv_news_recycler_item_image);
        Glide.with(context)
                .load(data.imageurl)
                .placeholder(R.drawable.nopic)
                .dontAnimate()
                .priority(Priority.HIGH)
                .into(pic);
        TextView titleView = holder.getView(R.id.tv_news_recycler_item_title);
        titleView.setText(data.title);

    }
}
上一篇下一篇

猜你喜欢

热点阅读