RecyclerView的基本使用

前言

RecyclerView自出现后,源自其强大的扩展性,越来越受到欢迎。
它成为了我们日常开发中使用频率最高的控件,所以有必要记录一下他的基础用法。

1.配置build.gradle

想要使用RecyclerView,我们首先要导入support-v7包,所以我们需要在build.gradle中加入如下代码用于自动导入support-v7包。

dependencies {
    ...
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    ...
}

2.设置布局文件

MainActivity的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
    
</RelativeLayout>

item的布局文件,这里的布局就只是显示一个文字

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    
    <TextView
        android:id="@+id/tv_item"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="moon"
        android:gravity="center"/>

</FrameLayout>

3.自定义Adapter

Adapter继承了RecyclerView.Adapter,在onCreateViewHolder中加载条目布局,在onBindViewHolder中将视图与数据进行绑定。

public class HomeAdapter extends RecyclerView.Adapter<MyViewHolder> {
    public List<String> mlist;
    public Context context;
    public OnItemClickListener mClickListener;

    public HomeAdapter(Context context,List<String>mlist){
        this.context=context;
        this.mlist=mlist;
    }

    public void removeData(int position){
        mlist.remove(position);
        notifyItemRemoved(position);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_recycler, viewGroup, false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder myViewHolder, final int i) {
        myViewHolder.textView.setText(mlist.get(i));
        if (mClickListener!=null){
            myViewHolder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos =myViewHolder.getLayoutPosition();
                    mClickListener.onItemClick(myViewHolder.textView,pos);
                }
            });
            myViewHolder.textView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos =myViewHolder.getLayoutPosition();
                    mClickListener.onItemLongClick(myViewHolder.textView,pos);
                    return false;
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return mlist.size();
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mClickListener = listener;
    }

    }


4.自定义ViewHolder

adapter最大的改进就是对ViewHolder进行了封装定义,我们只需要自定义一个ViewHolder继承RecyclerView.ViewHolder就可以了。

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView textView;
    
    public MyViewHolder(View view) {
        super(view);
        textView = (TextView) view.findViewById(R.id.tv_item);
    }
}

5.设置分割线

在我们的日常使用中,我们会发现默认的RecyclerView是没有分割线的,需要我们自己添加。
设置分割线有很多种方法,比如
1.直接在item.xml文件中在最下方指定一条分割线。
2.添加默认分割线:高度为2px,颜色为灰色

mRecyclerView.addItemDecoration(new RecycleViewDivider(mContext, LinearLayoutManager.VERTICAL));

3.自定义分割线
(最基本的分割线,包括垂直或者水平两个方向,可以设定颜色和高度。)

使用:
垂直方向:CommItemDecoration.createVertical(context, Color.BLUE,30)
水平方向:CommItemDecoration.createHorizontal(context, Color.BLUE,30)

代码如下:

public class CommItemDecoration extends RecyclerView.ItemDecoration {

        private static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
        private static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

        private int mSpace = 1;     //间隔
        private Rect mRect = new Rect(0,0,0,0);
        private Paint mPaint = new Paint();

        private int mOrientation;

        private CommItemDecoration(Context context, int orientation, @ColorInt int color, int space) {
            mOrientation = orientation;
            if(space>0){
                mSpace = space;
            }
            mPaint.setColor(color);
        }

        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDraw(c, parent, state);
            if (mOrientation == VERTICAL_LIST) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }
        }

        public 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; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mSpace;
                mRect.set(left,top,right,bottom);
                c.drawRect(mRect,mPaint);
            }
        }

        public 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; 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 + mSpace;
                mRect.set(left, top, right, bottom);
                c.drawRect(mRect,mPaint);
            }
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            if (mOrientation == VERTICAL_LIST) {
                outRect.set(0, 0, 0,mSpace);
            } else {
                outRect.set(0, 0, mSpace, 0);
            }
        }

        public static CommItemDecoration createVertical(Context context, @ColorInt int color, int height){
            return new CommItemDecoration(context,VERTICAL_LIST,color,height);
        }

        public static CommItemDecoration createHorizontal(Context context, @ColorInt int color, int width){
            return new CommItemDecoration(context,HORIZONTAL_LIST,color,width);
        }
    }

6.自定义点击事件

我们可以直接在直接在Adapter中的onBindViewHolder()方法中实现点击事件,但是我们也可以自己去定义点击事件
1)首先定义一个接口
我们在这里自定义了条目的点击事件和长按事件

public interface OnItemClickListener {
    void onItemClick(View view, int position);
    void onItemLongClick(View view,int postion);
}

2)再在Adapter中设置回调

public void setOnItemClickListener(OnItemClickListener listener) {
        this.mClickListener = listener;
    }

3)接下来对item中的控件进行点击事件监听并回调给我们自定义的监听

@Override
    public void onBindViewHolder(final MyViewHolder myViewHolder, final int i) {
        myViewHolder.textView.setText(mlist.get(i));
        if (mClickListener!=null){
            myViewHolder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos =myViewHolder.getLayoutPosition();
                    mClickListener.onItemClick(myViewHolder.textView,pos);
                }
            });
            myViewHolder.textView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos =myViewHolder.getLayoutPosition();
                    mClickListener.onItemLongClick(myViewHolder.textView,pos);
                    return false;
                }
            });
        }
    }

4)最后在Activity中进行监听

homeAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, final int position) {
                int i=position+1;
                Toast.makeText(MainActivity.this, "item  "+i, Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onItemLongClick(View view, final int postion) {
                int i=postion+1;
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("确认删除 item "+i+"?")
                        .setNegativeButton("取消",null)
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                homeAdapter.removeData(postion);
                            }
                        }).show();
            }
        });

7.实现效果

1)点击效果
在这里插入图片描述
2)长按效果
长按时会弹出对话框,删除时会有消失动画
在这里插入图片描述

8.实现GirdView

我们也可以使用RecyclerView来实现GirdView,只需要自定义横向的分割线,在MainActivity中设置:

recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
        recyclerView.addItemDecoration(CommItemDecoration.createHorizontal(this,Color.GREEN,2));

效果图:
在这里插入图片描述

最后

通过学习和整理出RecyclerView的基本使用后感觉对RecyclerView更多的感触,之前只知道对着书或者视频照着葫芦画瓢,现在也是对这一个常用的控件有了一定的了解,但是肯定还是存在很多漏洞,在以后的学习如果有了其他想法或者发现错误,会回来继续更正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值