RecyclerView在項(xiàng)目開(kāi)發(fā)中使用的頻率還是相當(dāng)高的,平時(shí)在網(wǎng)上看到文章大體都有介紹,總感覺(jué)有些欠缺,最近空閑下來(lái)了,終于有時(shí)間可以整理一下自己在開(kāi)發(fā)中使用的一些心得,僅供大家參考,文中說(shuō)漏的或者是不對(duì)的,還請(qǐng)各位大俠指出。
首先介紹一下recycleView的使用方法:
第一步:在gradle文件中引入recyclerview的包,否則無(wú)法使用。

第二步:編寫(xiě)xml文件,很簡(jiǎn)單直接引入就可以了。

第三步:初始化recyclerview控件,我這里用的是ButterKnife注冊(cè)工具。

然后為recyclerview準(zhǔn)備適配器,一般自定義一個(gè)adpater繼承RecyclerView.Adapter,然后創(chuàng)建自己ViewHolder繼承RecyclerView.ViewHolder,
實(shí)現(xiàn)onCreateViewHolder,onBindViewHolder,getItemCount三個(gè)方法,一般做如下處理就可以了。




然后再activity代碼中為adapter初始化數(shù)據(jù),將adapter綁定到recyclerview。

然后調(diào)用setLayoutManager方法,設(shè)置recyclerView的布局樣式,可以設(shè)置線性、網(wǎng)格、瀑布流以及分割線,詳細(xì)請(qǐng)看代碼中的注釋。
private void initView(int index) {
if(decoration !=null)
recyclerView.removeItemDecoration(decoration);
? ? switch (index){
case 0://線性上下滾動(dòng)
LinearLayoutManager manager =new LinearLayoutManager(this);
? ? ? ? ? ? recyclerView.setLayoutManager(manager);
break;
? ? ? ? case 1://線性水平滾動(dòng)
LinearLayoutManager manager1 =new LinearLayoutManager(this);
? ? ? ? ? ? manager1.setOrientation(LinearLayoutManager.HORIZONTAL);
? ? ? ? ? ? recyclerView.setLayoutManager(manager1);
break;
? ? ? ? case 2://網(wǎng)格上下滾動(dòng)
GridLayoutManager gridLayoutManager =new GridLayoutManager(this,4);
? ? ? ? ? ? recyclerView.setLayoutManager(gridLayoutManager);
break;
? ? ? ? case 3://網(wǎng)格水平滾動(dòng)
GridLayoutManager girdHorizontalLayoutManager =new GridLayoutManager(this,1);
? ? ? ? ? ? girdHorizontalLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
? ? ? ? ? ? recyclerView.setLayoutManager(girdHorizontalLayoutManager);
break;
? ? ? ? case 4://瀑布流上下滾動(dòng)
StaggeredGridLayoutManager staggeredGridVERTICALLayoutManager =new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
? ? ? ? ? ? recyclerView.setLayoutManager(staggeredGridVERTICALLayoutManager);
break;
? ? ? ? case 5://瀑布流水平滾動(dòng)
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);
}
分割線的使用
設(shè)置listView形式的分割線,需自己定義一個(gè)類(lèi)繼承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; //默認(rèn)是2px
? ? private PaintmPaint;
? ? //繪制默認(rèn)分割線
? ? public MyDividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
? ? ? ? mDivider = a.getDrawable(0);
? ? ? ? //系統(tǒng)屬性中獲取
? ? ? ? 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中執(zhí)行
? ? 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);
? ? ? ? }
}
}
然后再代碼中設(shè)置就可以了 如下:
MyDividerItemDecoration?decoration=new MyDividerItemDecoration(this, MyDividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(decoration);
設(shè)置網(wǎng)格形式的分割線,代碼如下:
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)
{
// 列數(shù)
? ? ? ? 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 且縱向滾動(dòng)
? ? ? ? ? ? if (orientation == StaggeredGridLayoutManager.VERTICAL)
{
childCount = childCount - childCount % spanCount;
? ? ? ? ? ? ? ? // 如果是最后一行,則不需要繪制底部
? ? ? ? ? ? ? ? if (pos >= childCount)
return true;
? ? ? ? ? ? }else
? ? ? ? ? ? // StaggeredGridLayoutManager 且橫向滾動(dòng)
? ? ? ? ? ? {
// 如果是最后一行,則不需要繪制底部
? ? ? ? ? ? ? ? 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());
? ? ? ? }
}
}
然后在代碼中設(shè)置就ok了:
DividerGridItemDecoration?decoration=new DividerGridItemDecoration(this);
recyclerView.addItemDecoration(decoration);
添加側(cè)滑刪除和拖拽移動(dòng)
通過(guò)為RecycleView綁定觸摸事件,就可以實(shí)現(xiàn):

為recyclerView添加點(diǎn)擊事件
這里推薦 在adapter中添加接口進(jìn)行事件監(jiān)聽(tīng)的回調(diào)來(lái)實(shí)現(xiàn),代碼如下,詳細(xì)見(jiàn)代碼注釋?zhuān)?/p>
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)//設(shè)置監(jiān)聽(tīng)事件,在此處回調(diào)
listener.onItemClick(view,position); } });
holder.itemText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
? ? ? ? ? ? public boolean onLongClick(View view) {
new AlertDialog.Builder(view.getContext())
.setTitle("確認(rèn)刪除嗎")
.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的添加動(dòng)畫(huà),在adapter中的onBindViewHolder方法中使用屬性動(dòng)畫(huà)實(shí)現(xiàn),此處只是一例,可以自己稍加創(chuàng)意

淺嘗截止,感覺(jué)有點(diǎn)亂,希望能幫到你~~~~~