RecycleView Adapter封装使用
程序员文章站
2022-05-15 19:30:19
...
参照不同大神的博客 , 修改而来, 望大神们海涵!!!!
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>
运行结果
改成流式布局之后
上一篇: 仿9GAG制作过程(四)
推荐阅读
-
c#使用简单工厂模式实现生成html文件的封装类分享
-
Kotlin + Retrofit + RxJava简单封装使用详解
-
IOS 使用Block二次封装AFNetworking 3.0详解
-
Python中使用asyncio 封装文件读写
-
Android开发之缓冲dialog对话框创建、使用与封装操作
-
Android RecycleView使用(CheckBox全选、反选、单选)
-
iOS中封装.framework及使用的方法详解
-
Android RecycleView添加head配置封装的实例
-
Python中使用asyncio 封装文件读写
-
Android开发之缓冲dialog对话框创建、使用与封装操作