Android RecyclerView使用详解

写在前头

       为什么要使用RecyclerView,RecyclerViwe使用灵活,可以实现多种布局效果,完全可以替代ListView和GridView,而且其适配器的写法也很简单,连ViewHodler也帮你做了处理,使ViewHolder的使用变得更加标准化。RecyclerViwe还提供了横向和纵向等多种效果,均可以通过一句代码实现,方法简便。最后顺便提一句RecyclerView配合ButterKnife使用效果更佳。


RecyclerView提供了三种布局管理器:

  •  LinerLayoutManager 以垂直或者水平列表方式(和ListView效果类似)
  • GridLayoutManager 以网格方式(和GridView效果类似)
  • StaggeredGridLayoutManager 以瀑布流方式

 

基本使用

一、添加依赖

compile 'com.android.support:recyclerview-v7:26.1.0'


二、编写适配器

public class mAdapter extends RecyclerView.Adapter
{
        private ArrayList Users;
        private BaseViewHolder mBaseViewHolder;
        private Context context;
	//构造方法
        public mAdapter(ArrayList Users,Context context)
        {
            this.Users = Users;
            this.context = context;
        }
        @Override
        public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
	    //传入ViewHolder
            mBaseViewHolder = new BaseViewHolder(LayoutInflater.from(context).inflate(
                    R.layout.main_activity,parent,false));//这样传递可以避免RecyclerViwe子项宽度铺不满的问题
            return mBaseViewHolder;
        }

        @Override
        public void onBindViewHolder(CommentsBaseViewHolder holder, int position) {
            holder.setData(Users.get(position));
        }

        @Override
        public int getItemCount() {
            //返回数据长度
            return Users.size();
        }

        public class BaseViewHolder extends RecyclerView.ViewHolder {
            private TextView UserSex;
            private TextView UserName;
	    //绑定View
            public CommentsBaseViewHolder(View itemView) {
                super(itemView);
                UserSex = itemView.findViewById(R.id.user_sex);
                UserName = itemView.findViewById(R.id.user_name);
            }
            public void setData(UserInfo user){
                UserSex.setText(user.sex);
                UserName.setText(user.name);
            }
        }
}

 

三、代码中实现

LinearLayoutManager manager = new LinearLayoutManager(CommentAcitivity.this);//要实现不同的效果可以更换不同的布局管理器实现
mRecyclerViwe.setLayoutManager(manager);
mAdapter myAdapter = new mAdapter(UserInfos,CommentAcitivity.this);
mRecyclerViwe.setAdapter(myAdapter);

如果想要个RecyclerView添加分割线 我们只需要调用mRecyclerView.addItemDecoration()这个方法即可

 

 

避免数据错误

    RecyclerView是根据布局的类型来返回item,只有当类型不同时才会返回不同的item,避免出现数据错乱我们需要重新复写其获取类型的方法

 @Override
 public int getItemViewType(int position) {
      return position;
 }

 

 

RecyclerView实现多种布局混合使用

要实现一个adapter多种布局其实也不难实现

一、给不同的position设置不同的类型

 @Override
public int getItemViewType(int position) {
    //在这里设置不同类型 我就不再写了
    return super.getItemViewType(position);
}

 

二、创建不同的Holder,这样你的类的继承就需要做一点改变了

public class mAdapter extends RecyclerView.Adapter

注意:Holder的泛型是RecyclerView.ViewHolder而不是你的Holder类

 

三、通过viewType在onCreateViewHolder中设置不同的Holder即可

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
	RecyclerView.ViewHolder holder = null;
	switch (viewType)
	{
	case TYPE_ITEM:
		holder = new MyViewHolder(LayoutInflater.from(context).inflate(
				R.layout.activity_first,false));
		break;
	case TYPE_FOOTER:
		holder = new FootViewHolder(LayoutInflater.from(context).inflate(
				R.layout.activity_second,parent,false));
		break;
        case TYPE_HEAD:
                holder = new TopicHeadHolder(LayoutInflater.from(context).inflate(
                                R.layout.activity_three,parent,false));
                break;
	}

	return holder;
}

 

RycyclerView实现自定义分割线

这是一个GridLinearLayout横竖都有分割线的一个自定义分割线

public class GridDivider extends RecyclerView.ItemDecoration {

    private Drawable mDividerDarwable;
    private int mDividerHight = 1;
    private Paint mColorPaint;


    public final int[] ATRRS = new int[]{android.R.attr.listDivider};

    public GridDivider(Context context) {
        final TypedArray ta = context.obtainStyledAttributes(ATRRS);
        this.mDividerDarwable = ta.getDrawable(0);
        ta.recycle();
    }

    /*
     int dividerHight  分割线的线宽
     int dividerColor  分割线的颜色
     */
    public GridDivider(Context context, int dividerHight, int dividerColor) {
        this(context);
        mDividerHight = dividerHight;
        mColorPaint = new Paint();
        mColorPaint.setColor(dividerColor);
    }

    /*
     int dividerHight  分割线的线宽
     Drawable dividerDrawable  图片分割线
     */
    public GridDivider(Context context, int dividerHight, Drawable dividerDrawable) {
        this(context);
        mDividerHight = dividerHight;
        mDividerDarwable = dividerDrawable;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        //画水平和垂直分割线
        drawHorizontalDivider(c, parent);
        drawVerticalDivider(c, parent);
    }

    public void drawVerticalDivider(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;

            int left = 0;
            int right = 0;

            //左边第一列
            if ((i % 3) == 0) {
                //item左边分割线
                left = child.getLeft();
                right = left + mDividerHight;
                mDividerDarwable.setBounds(left, top, right, bottom);
                mDividerDarwable.draw(c);
                if (mColorPaint != null) {
                    c.drawRect(left, top, right, bottom, mColorPaint);
                }
                //item右边分割线
                left = child.getRight() + params.rightMargin - mDividerHight;
                right = left + mDividerHight;
            } else {
                //非左边第一列
                left = child.getRight() + params.rightMargin - mDividerHight;
                right = left + mDividerHight;
            }
            //画分割线
            mDividerDarwable.setBounds(left, top, right, bottom);
            mDividerDarwable.draw(c);
            if (mColorPaint != null) {
                c.drawRect(left, top, right, bottom, mColorPaint);
            }

        }
    }

    public void drawHorizontalDivider(Canvas c, RecyclerView parent) {

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            final int left = child.getLeft() - params.leftMargin - mDividerHight;
            final int right = child.getRight() + params.rightMargin;
            int top = 0;
            int bottom = 0;

            // 最上面一行
            if ((i / 3) == 0) {
                //当前item最上面的分割线
                top = child.getTop();
                //当前item下面的分割线
                bottom = top + mDividerHight;
                mDividerDarwable.setBounds(left, top, right, bottom);
                mDividerDarwable.draw(c);
                if (mColorPaint != null) {
                    c.drawRect(left, top, right, bottom, mColorPaint);
                }
                top = child.getBottom() + params.bottomMargin;
                bottom = top + mDividerHight;
            } else {
                top = child.getBottom() + params.bottomMargin;
                bottom = top + mDividerHight;
            }
            //画分割线
            mDividerDarwable.setBounds(left, top, right, bottom);
            mDividerDarwable.draw(c);
            if (mColorPaint != null) {
                c.drawRect(left, top, right, bottom, mColorPaint);
            }
        }
    }
}

 

效果图(效果如下面的键盘):

Android RecyclerView使用详解_第1张图片

 

最后

       RecyclerView的使用方法更为简便,且使用的方面更多,这也使得RecyclerView成为了目前使用较为广泛的布局。推荐一款开源的RecyclerView适配器----BRVAH(可到github查看),它做了很多动画效果,使得RecyclerView的使用更加容易了。

你可能感兴趣的:(Android)