RecyclerView在项目开发中使用的频率还是相当高的,平时在网上看到文章大体都有介绍,总感觉有些欠缺,最近空闲下来了,终于有时间可以整理一下自己在开发中使用的一些心得,仅供大家参考,文中说漏的或者是不对的,还请各位大侠指出。
首先介绍一下recycleView的使用方法:
第一步:在gradle文件中引入recyclerview的包,否则无法使用。
第二步:编写xml文件,很简单直接引入就可以了。
第三步:初始化recyclerview控件,我这里用的是ButterKnife注册工具。
然后为recyclerview准备适配器,一般自定义一个adpater继承RecyclerView.Adapter,然后创建自己ViewHolder继承RecyclerView.ViewHolder,
实现onCreateViewHolder,onBindViewHolder,getItemCount三个方法,一般做如下处理就可以了。
然后再activity代码中为adapter初始化数据,将adapter绑定到recyclerview。
然后调用setLayoutManager方法,设置recyclerView的布局样式,可以设置线性、网格、瀑布流以及分割线,详细请看代码中的注释。
private void initView(int index) {
if(decoration !=null)
recyclerView.removeItemDecoration(decoration);
switch (index){
case 0://线性上下滚动
LinearLayoutManager manager =new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
break;
case 1://线性水平滚动
LinearLayoutManager manager1 =new LinearLayoutManager(this);
manager1.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(manager1);
break;
case 2://网格上下滚动
GridLayoutManager gridLayoutManager =new GridLayoutManager(this,4);
recyclerView.setLayoutManager(gridLayoutManager);
break;
case 3://网格水平滚动
GridLayoutManager girdHorizontalLayoutManager =new GridLayoutManager(this,1);
girdHorizontalLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(girdHorizontalLayoutManager);
break;
case 4://瀑布流上下滚动
StaggeredGridLayoutManager staggeredGridVERTICALLayoutManager =new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridVERTICALLayoutManager);
break;
case 5://瀑布流水平滚动
StaggeredGridLayoutManager staggeredGridHORIZONTALLayoutManager =new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(staggeredGridHORIZONTALLayoutManager);
break;
case 6:
LinearLayoutManager listViewItemDecoration =new LinearLayoutManager(this);
recyclerView.setLayoutManager(listViewItemDecoration);
decoration =new MyDividerItemDecoration(this, MyDividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(decoration);
break;
case 7:
StaggeredGridLayoutManager staggeredGridVERTICALLayoutManagerwithDecoration =new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridVERTICALLayoutManagerwithDecoration);
decoration =new DividerGridItemDecoration(this);
recyclerView.addItemDecoration(decoration);
break;
}
recyclerView.setAdapter(adapter);
}
分割线的使用
设置listView形式的分割线,需自己定义一个类继承RecyclerView.ItemDecoration就可以了 如下代码:
public class MyDividerItemDecorationextends RecyclerView.ItemDecoration {
private static final int[]ATTRS =new int[]{
android.R.attr.listDivider
};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private int mOrientation;
private DrawablemDivider;
private int mDividerHeight =2; //默认是2px
private PaintmPaint;
//绘制默认分割线
public MyDividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
//系统属性中获取
a.recycle();
setOrientation(orientation);
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public MyDividerItemDecoration(Context context, int orientation, int drawableId) {
this(context, orientation);
mDivider = ContextCompat.getDrawable(context, drawableId);
mDividerHeight =mDivider.getIntrinsicHeight();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public MyDividerItemDecoration(Context context, int orientation, int dividerHeight, int dividerColor) {
this(context, orientation);
mDividerHeight = dividerHeight;
mPaint =new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
}
private void setOrientation(int orientation) {
if (orientation !=HORIZONTAL_LIST && orientation !=VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientaion");
}
mOrientation = orientation;
}
@Override
//在RecyclerView的onDraw中执行
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation ==VERTICAL_LIST) {
drawVertical(c, parent);
}else {
drawHorizontal(c, parent);
}
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i =0; i < childCount-1; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left +mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i =0; i < childCount-1; i++) {
final View child = parent.getChildAt(i);
RecyclerView v =new RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top +mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation ==VERTICAL_LIST) {
outRect.set(0, 0, 0, mDividerHeight);
}else {
outRect.set(0, 0, mDividerHeight, 0);
}
}
}
然后再代码中设置就可以了 如下:
MyDividerItemDecoration decoration=new MyDividerItemDecoration(this, MyDividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(decoration);
设置网格形式的分割线,代码如下:
public class DividerGridItemDecorationextends RecyclerView.ItemDecoration {
private static final int[]ATTRS =new int[] { android.R.attr.listDivider };
private DrawablemDivider;
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)
{
// 列数
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManagerinstanceof GridLayoutManager)
{
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
}else if (layoutManagerinstanceof StaggeredGridLayoutManager)
{
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
}
return spanCount;
}
public void drawHorizontal(Canvas c, 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(c);
}
}
public void drawVertical(Canvas c, 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(c);
}
}
private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManagerinstanceof GridLayoutManager)
{
if ((pos +1) % spanCount ==0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
}else if (layoutManagerinstanceof 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 (layoutManagerinstanceof GridLayoutManager)
{
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
return true;
}else if (layoutManagerinstanceof 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();
if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
{
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
}else
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight());
}
}
}
然后在代码中设置就ok了:
DividerGridItemDecoration decoration=new DividerGridItemDecoration(this);
recyclerView.addItemDecoration(decoration);
添加侧滑删除和拖拽移动
通过为RecycleView绑定触摸事件,就可以实现:
为recyclerView添加点击事件
这里推荐 在adapter中添加接口进行事件监听的回调来实现,代码如下,详细见代码注释:
public class RecyclerViewAdapterextends RecyclerView.Adapter {
private ListmList;
private onclickListener listener;//将接口作为成员变量
public void setListener(onclickListener listener) { this.listener = listener; }//添加set方法,供外部使用
public RecyclerViewAdapter(List mList) {
this.mList = mList;
}
public interface
@Override
public ViewHolderonCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
String content =mList.get(position);
holder.itemText.setText(content);
holder.itemText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(listener != null)//设置监听事件,在此处回调
listener.onItemClick(view,position); } });
holder.itemText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
new AlertDialog.Builder(view.getContext())
.setTitle("确认删除吗")
.setNegativeButton("取消",null)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (flag ==true){
removeData(holder.getAdapterPosition());
flag=false;
}else{
addData(holder.getAdapterPosition());
flag=true;
}
}
}).show();
return false;
}
});
}
@Override
public int getItemCount() {
return mList !=null?mList.size():0;
}
static class ViewHolderextends RecyclerView.ViewHolder {
@BindView(R.id.item_text)
TextViewitemText;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
public interface onclickListener{ void onItemClick(View view,int position); }//添加接口,供外部使用
}
为recyclerView的添加动画,在adapter中的onBindViewHolder方法中使用属性动画实现,此处只是一例,可以自己稍加创意
浅尝截止,感觉有点乱,希望能帮到你~~~~~