RecycleView Adapter封装使用

参照不同大神的博客 , 修改而来, 望大神们海涵!!!!

build.gradle引用

dependencies {
    implementation 'com.android.support:recyclerview-v7:26.1.0'
}

适配器主体
这里设置了两种方式设置数据源
1.构造函数传参
2.初始空适配器,出入数据源刷新适配器

public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewHolder> {
    /*布局ID*/
    private int mLayoutID = -1;
    /*数据源*/
    private List<T> mListData = null;
    /*上下文*/
    private Context mContext = null;
    /*点击事件*/
    private OnItemClickListener mClickListener = null;
    /*单击事件和长单击事件的屏蔽标识*/
    private boolean clickFlag = true;

    /*上下文,布局ID,数据源*/
    public BaseRecyclerViewAdapter(Context context, int layoutId, List<T> data) {
        this.mLayoutID = layoutId;
        this.mListData = data;
        this.mContext = context;
    }

    /*上下文,布局ID*/
    public BaseRecyclerViewAdapter(int mLayoutID, Context mContext) {
        this.mLayoutID = mLayoutID;
        this.mContext = mContext;
    }

    /*设置数据源*/
    public void setData(List<T> data) {
        this.mListData = data;
        notifyDataSetChanged();
    }

    /*在任意位置添加 Item */
    public void addData(int position, T data) {
        mListData.add(position, data);
        //如果想使用动画必用
        notifyItemInserted(position);
    }

    /*移除某位置的数据*/
    public void removeData(int position) {
        mListData.remove(position);
        //如果想使用动画必用
        notifyItemRemoved(position);
    }

    /*创建复用器*/
    @Override
    public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View inflate = LayoutInflater.from(mContext).inflate(mLayoutID, parent, false);
        inflate.setBackgroundResource(R.drawable.recycle_item);
        final BaseRecyclerViewHolder holder = new BaseRecyclerViewHolder(inflate, mContext);

        /*单击事件回调*/
        inflate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (clickFlag) {
                    if (mClickListener != null) {
                        mClickListener.OnItemClick(v, holder.getLayoutPosition());
                    }
                }
                clickFlag = true;
            }
        });
        //单击长按事件回调
        inflate.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mClickListener != null) {
                    mClickListener.OnItemLongClick(v, holder.getLayoutPosition());
                }
                clickFlag = false;
                return false;
            }
        });
        return holder;
    }

    /*绑定ViewHolder*/
    @Override
    public void onBindViewHolder(BaseRecyclerViewHolder holder, int position) {
        convert(holder, mListData.get(position),position);
    }

    protected abstract void convert(BaseRecyclerViewHolder holder, T bean,int position);

    /*获取条目数量*/
    @Override
    public int getItemCount() {
        return (mListData == null || mListData.isEmpty()) ? 0 : mListData.size();
    }

    /*设置点击事件*/
    public void setOnItemClickListener(OnItemClickListener onClickListener) {
        this.mClickListener = onClickListener;
    }

    public interface OnItemClickListener {
        /*点击事件*/
        void OnItemClick(View view, int position);

        /*长按点击事件*/
        void OnItemLongClick(View view, int position);
    }
}

ViewHolder
这里提供了两种设置控件的方法:
(int , String)适用于最基本的显示;
(int,String,CallBack)适用于稍复杂的控件显示,如控件有点击事件。。。。;

public class BaseRecyclerViewHolder extends RecyclerView.ViewHolder {
    private View inflate;
    private Context mContext;

    public BaseRecyclerViewHolder(View itemView, Context context) {
        super(itemView);
        this.inflate = itemView;
        this.mContext = context;
    }

    /*设置TextView 控件*/
    public void setText(int tvID, String text, CallBack<TextView> callBack) {
        TextView tx = (TextView) inflate.findViewById(tvID);
        tx.setText(text);
        if (callBack != null) {
            callBack.run(tx);
        }
    }

    /*设置ImageView 控件*/
    public void setImageResource(int ivID, int resouceId, CallBack<ImageView> callBack) {
        ImageView img = (ImageView) inflate.findViewById(ivID);
        img.setImageResource(resouceId);
        if (callBack != null) {
            callBack.run(img);
        }
    }

    /*设置CheckBox 控件*/
    public void setCheckBox(int cbID, boolean cb, CallBack<CheckBox> callBack) {
        CheckBox cbox = (CheckBox) inflate.findViewById(cbID);
        cbox.setChecked(cb);
        if (callBack != null) {
            callBack.run(cbox);
        }
    }

    /*设置ImageButton 控件*/
    public void setImageButton(int ibtnID, CallBack<ImageButton> callBack) {
        ImageButton ibtn = (ImageButton) inflate.findViewById(ibtnID);
        if (callBack != null) {
            callBack.run(ibtn);
        }
    }

    /*设置LinearLayout 控件*/
    public void setLinearLayout(int layoutID, CallBack<LinearLayout> callBack) {
        LinearLayout layout = (LinearLayout) inflate.findViewById(layoutID);
        if (callBack != null) {
            callBack.run(layout);
        }
    }

    /*设置RelativeLayout 控件*/
    public void setRelativeLayout(int layoutID, CallBack<RelativeLayout> callBack) {
        RelativeLayout layout = (RelativeLayout) inflate.findViewById(layoutID);
        if (callBack != null) {
            callBack.run(layout);
        }
    }

    /*设置GridView 控件*/
    public void setGridView(int gridID, CallBack<GridView> callBack) {
        GridView grid = (GridView) inflate.findViewById(gridID);
        if (callBack != null) {
            callBack.run(grid);
        }
    }

    /*回调函数*/
    public interface CallBack<T> {
        void run(T t);
    }
}

此处回调函数CallBack做了调整, 之前使用时需要转换类型才可以使用, 添加了泛型之后可以不用再转换类型
分割线
这里的分割线可以适用于部分RecycleView ,有些需要进行微调

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;

    public DividerGridItemDecoration(Context context) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        /*绘画横向间隔  — */
        drawHorizontal(c, parent);
        /*绘画纵向间隔  | */
        drawVertical(c, parent);
    }

    private int getSpanCount(RecyclerView parent) {
        /*获取RecycleView 的列数*/
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
        }
        return spanCount;
    }

    public void drawHorizontal(Canvas canvas, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
    }

    public void drawVertical(Canvas canvas, RecyclerView parent) {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin;
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicWidth();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(canvas);
        }
    }

    /*判断是否是最后一列*/
    private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            if ((pos + 1) % spanCount == 0) {
                // 如果是最后一列,则不需要绘制右边
                return true;
            }
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                if ((pos + 1) % spanCount == 0) {
                    // 如果是最后一列,则不需要绘制右边
                    return true;
                }
            } else {
                childCount = childCount - childCount % spanCount;
                if (pos >= childCount)
                    // 如果是最后一列,则不需要绘制右边
                    return true;
            }
        }
        return false;
    }

    /*判断是否是最后一行*/
    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            childCount = childCount - childCount % spanCount;
            if (pos >= childCount) // 如果是最后一行,则不需要绘制底部
                return true;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            // StaggeredGridLayoutManager 且纵向滚动
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;
                // 如果是最后一行,则不需要绘制底部
                if (pos >= childCount)
                    return true;
            } else {
                // StaggeredGridLayoutManager 且横向滚动
                // 如果是最后一行,则不需要绘制底部
                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition,
                               RecyclerView parent) {
        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        int intrinsicWidth = mDivider.getIntrinsicWidth();
        int intrinsicHeight = mDivider.getIntrinsicHeight();
        if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
            // 如果是最后一行,则不需要绘制底部
            outRect.set(0, 0, intrinsicWidth, 0);
        } else if (isLastColum(parent, itemPosition, spanCount, childCount)) {
            // 如果是最后一列,则不需要绘制右边
            outRect.set(0, 0, 0, intrinsicHeight);
        } else {
            outRect.set(0, 0, intrinsicWidth,
                    intrinsicHeight);
        }
    }
}

使用
MainActivity.class

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecycleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_main);
        /*初始化空间*/
        mRecycleView = (RecyclerView) findViewById(R.id.recycle);
        /*设置布局管理器 */
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        gridLayoutManager.setOrientation(GridLayoutManager.VERTICAL);
        mRecycleView.setLayoutManager(gridLayoutManager);
//        mRecycleView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.HORIZONTAL));
//        mRecycleView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));

        /*设置分割线*/
        mRecycleView.addItemDecoration(new DividerGridItemDecoration(this));

        /*初始化数据*/
        List<MyBean> list = new ArrayList<>();
        for (int i = 0; i < 20000; i++) {
            MyBean myBean = new MyBean();
            myBean.setName("这是第" + (i + 1) + "条数据");
            list.add(myBean);
        }
        /*设置适配器*/
        RecycleAdapterTest adapter = new RecycleAdapterTest(this);
        adapter.setData(list);
        mRecycleView.setAdapter(adapter);
        /*设置操作动画*/
        mRecycleView.setItemAnimator(new DefaultItemAnimator());
        /*设置点击事件*/
        adapter.setOnItemClickListener(new BaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void OnItemClick(View view, int position) {
                Toast.makeText(MainActivity.this, "=============>>>点击" + position, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void OnItemLongClick(View view, int position) {
                Toast.makeText(MainActivity.this, "长点击======>>>" + position, Toast.LENGTH_SHORT).show();
            }
        });
    }

}

MyBean

public class MyBean{
    private String name;
    private String np;
    private int iv;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIv() {
        return iv;
    }

    public void setIv(int iv) {
        this.iv = iv;
    }

    public String getNp() {
        return np;
    }

    public void setNp(String np) {
        this.np = np;
    }
}

适配器使用 RecycleAdapterTest
这里的图片的点击事件会抢夺 BaseRecyclerViewAdapter中的图片区域的焦点

public class RecycleAdapterTest extends BaseRecyclerViewAdapter<MyBean> {
    int[] imgs = {R.mipmap.p1, R.mipmap.p2, R.mipmap.p3, R.mipmap.p4, R.mipmap.p5, R.mipmap.p6,};

    public RecycleAdapterTest(Context mContext) {
        super(R.layout.home_masonry_item, mContext);
    }

    @Override
    protected void convert(BaseRecyclerViewHolder holder, MyBean bean, int position) {
        MyBean p = bean;

        /*文字部分只作为显示*/
        holder.setText(R.id.masonry_item_title, p.getName(),null);

        /*图片部分设置点击事件*/
        holder.setImageResource(R.id.masonry_item_img, imgs[position % 6], new BaseRecyclerViewHolder.CallBack<ImageView>() {
            @Override
            public void run(ImageView imageView) {
                imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(v.getContext(), "这是点击", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

}

* layout_main 布局*

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycle"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

home_masonry_item.xml 布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#fff">

    <ImageView
        android:src="@mipmap/p1"
        android:id="@+id/masonry_item_img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"/>
    <TextView
        android:text="文字部分"
        android:id="@+id/masonry_item_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"/>
</LinearLayout>

这里写图片描述
* divider.xml *
分割线的样式style

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:centerColor="#ff00ff00"
        android:endColor="#ff0000ff"
        android:startColor="#ffff0000"
        android:type="linear" />
    <size android:height="5dp" android:width="5dp"/>
</shape>

这里写图片描述
运行结果
这里写图片描述

改成流式布局之后
这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值