RecyclerView完全使用手冊(cè)

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ú)法使用。

app項(xiàng)目中的build.gradle文件

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


xml布局文件

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


然后為recyclerview準(zhǔn)備適配器,一般自定義一個(gè)adpater繼承RecyclerView.Adapter,然后創(chuàng)建自己ViewHolder繼承RecyclerView.ViewHolder,

實(shí)現(xiàn)onCreateViewHolder,onBindViewHolder,getItemCount三個(gè)方法,一般做如下處理就可以了。


創(chuàng)建一個(gè)Viewholder類(lèi)
在oncreatViewHolder方法中加載布局初始化ViewHolder類(lèi)
在onBindViewholder方法中綁定數(shù)據(jù)


初始化item個(gè)數(shù)

然后再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)亂,希望能幫到你~~~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容