RecyclerView完全使用手册

RecyclerView在项目开发中使用的频率还是相当高的,平时在网上看到文章大体都有介绍,总感觉有些欠缺,最近空闲下来了,终于有时间可以整理一下自己在开发中使用的一些心得,仅供大家参考,文中说漏的或者是不对的,还请各位大侠指出。

首先介绍一下recycleView的使用方法:

第一步:在gradle文件中引入recyclerview的包,否则无法使用。

app项目中的build.gradle文件

第二步:编写xml文件,很简单直接引入就可以了。


xml布局文件

第三步:初始化recyclerview控件,我这里用的是ButterKnife注册工具。


然后为recyclerview准备适配器,一般自定义一个adpater继承RecyclerView.Adapter,然后创建自己ViewHolder继承RecyclerView.ViewHolder,

实现onCreateViewHolder,onBindViewHolder,getItemCount三个方法,一般做如下处理就可以了。


创建一个Viewholder类
在oncreatViewHolder方法中加载布局初始化ViewHolder类
在onBindViewholder方法中绑定数据


初始化item个数

然后再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方法中使用属性动画实现,此处只是一例,可以自己稍加创意


浅尝截止,感觉有点乱,希望能帮到你~~~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容