recyclerview适配器(recyclerview万能适配器)

RecyclerView,它是Android5.0的时候出来的一个新控件,主要目的就是替代的ListView和GridView控件,也就是说RecyclerView能够实现ListView控件和GridView中的效果,甚至比原来的更好,更方便,关于RecyclerView的使用本章不做讲解,请自行百度。

 

本次讲解的RecyclerView万能适配器相比网上的一些例子更加简单,功能更多

 

通用ViewHoler

package com.cccollector.library.baseadapter;

import android.graphics.Bitmap;
import android.util.SparseArray;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;

public class BaseViewHolder extends RecyclerView.ViewHolder {


    private SparseArray mViews = new SparseArray<>();//用来存储控件
    private View mConvertView;//布局


    public BaseViewHolder(@NonNull View itemView) {
        super(itemView);
        mConvertView = itemView;
    }

    public static BaseViewHolder getInstance(View itemView) {
        return new BaseViewHolder(itemView);
    }


    /**
     * 通过viewid获取控件
     */
    public View getView(@IdRes int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = mConvertView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return view;
    }

    public BaseViewHolder setText(@IdRes int viewId, String text) {
        ((TextView) getView(viewId)).setText(text);
        return this;
    }

    public BaseViewHolder setSrc(@IdRes int viewId, int resource) {
        ((ImageView) getView(viewId)).setImageResource(resource);
        return this;
    }

    public BaseViewHolder setSrc(@IdRes int viewId, Bitmap resource) {
        ((ImageView) getView(viewId)).setImageBitmap(resource);
        return this;
    }
    //可以自行添加你需要的方法

    //设置控件是否隐藏
    public BaseViewHolder setVisibility(@IdRes int viewId, @Visibility int visibility) {
        getView(viewId).setVisibility(visibility);
        return this;
    }

    /**
     * 条目点击事件
     *
     * @param onItemClickListener
     * @return
     */
    public BaseViewHolder setOnItemClickListener(final OnItemClickListener onItemClickListener) {
        mConvertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null)
                    onItemClickListener.onClick();
            }
        });
        return this;
    }

    /**
     * 条目上按钮点击事件
     *
     * @param viewId
     * @param onItemClickListener
     * @return
     */
    public BaseViewHolder setOnItemChildAtClickListener(@IdRes int viewId, final OnItemClickListener onItemClickListener) {
        getView(viewId).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null)
                    onItemClickListener.onClick();
            }
        });
        return this;
    }

    public interface OnItemClickListener {
        void onClick();
    }

    /**
     * @hide
     */
    @IntDef({VISIBLE, INVISIBLE, GONE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Visibility {
    }
}

代码中,创建了BaseViewHolder,继承了RecyclerView的ViewHoler,使用SparseArray来保存我们控件的一些信息。通过主要的getView()方法来获取相对应的控件,最后调用getView()封装了一些常用方法。

通用适配器

package com.cccollector.library.baseadapter;

import android.content.Context;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.collection.SparseArrayCompat;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

abstract public class CommonAdapter extends RecyclerView.Adapter {
    private static final int BASE_ITEM_TYPE_HEADER = 100000;
    private static final int BASE_ITEM_TYPE_FOOTER = 200000;


    private List mDataList = new ArrayList<>();//数据集合
    private SparseArrayCompat mItemTypes = new SparseArrayCompat();    //类型集合


    //头集合 尾结合
    private SparseArrayCompat mHeaderViews = new SparseArrayCompat<>();
    private SparseArrayCompat mFootViews = new SparseArrayCompat<>();

    public CommonAdapter(List dataList) {
        mDataList.clear();
        mDataList.addAll(dataList);
        //按照TYPE类型分类
        for (int i = 0; i < mDataList.size(); i++) {
            int type = getItemType(mDataList.get(i));
            mItemTypes.put(i, type);
        }
    }


    /**
     * 添加头部方法
     *
     * @param view
     */
    public void addHeaderView(View view) {
        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
    }

    /**
     * 添加尾部方法
     *
     * @param view
     */
    public void addFootView(View view) {
        mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
    }

    @Override
    public int getItemViewType(int position) {
        if (position < mHeaderViews.size()) {
            return mHeaderViews.keyAt(position);
        } else if (position >= mHeaderViews.size() + mDataList.size()) {
            return mFootViews.keyAt(position - mHeaderViews.size() + mDataList.size());
        }
        return mItemTypes.keyAt(position - mHeaderViews.size());
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        if (mHeaderViews.get(viewType) != null) {
            return BaseViewHolder.getInstance(mHeaderViews.get(viewType));
        } else if (mFootViews.get(viewType) != null) {
            return BaseViewHolder.getInstance(mFootViews.get(viewType));
        } else if (mItemTypes.get(viewType) != null) {
            int viewId = mItemTypes.get(viewType);
            Context context = viewGroup.getContext();
            View view = LayoutInflater.from(context).inflate(viewId, viewGroup, false);
            return BaseViewHolder.getInstance(view);
        }

        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull BaseViewHolder viewHolder, int position) {
        int viewType = getItemViewType(position);

        if (mHeaderViews.get(viewType) != null) {
            // convert(viewHolder,mHeaderViews.get(viewType).getId(),mDataList.get(position));
        } else if (mFootViews.get(viewType) != null) {
            // convert(viewHolder,mFootViews.get(viewType).getId(),mDataList.get(position));
        } else if (mItemTypes.get(viewType) != null) {
            convert(viewHolder, mItemTypes.get(viewType), mDataList.get(position - mHeaderViews.size()));
        }
    }

    @Override
    public int getItemCount() {
        return mHeaderViews.size() + mDataList.size() + mFootViews.size();
    }

    /**
     * 设置类型
     * @param item 数据
     * @return 返回的布局类型
     */
    protected abstract int getItemType(T item);//设置类型

    protected abstract void convert(BaseViewHolder viewHolder, int layoutId, T item);


}

由于添加了加头加尾功能代码多了一点,创建CommonAdapter 泛型类型是本类。通过getItemType()在构造方法中确定布局的类型。实现多布局在convert()方法中把布局类型返回出去,实现分类型显示

如何使用

        mRecyclerview = findViewById(R.id.recyclerview);
        mRecyclerview.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerview.setAdapter(new CommonAdapter(mList) {
            @Override
            protected int setItemType(Mode item) {
                if (item.getType() == 1) {
                    return R.layout.item;
                } else {
                    return R.layout.item2;
                }
            }

            @Override
            protected void convert(BaseViewHolder viewHolder, int layoutId, Mode item) {
                switch (layoutId) {
                    case R.layout.item:
                        viewHolder.setText(R.id.textview, item.getTitle());
                        break;
                    case R.layout.item2:
                        viewHolder.setText(R.id.textview, item.getTitle());
                        break;
                }
            }
        });

由于代码较少使用了内部类方式


到此已经完成了万能适配器的开发。如有好的建议,欢迎指出谢谢

你可能感兴趣的:(RecyclerView)