1.RecyclerView 导入包的方式(可以避免build高版本调用低版本v7包编译不过问题)

compile ‘com.android.support:recyclerview-v7:+’

2.RecyclerView setAdapter前需要先设置LayoutManager,原因:明确其是水平展示还是纵向显示

3.RecyclerView 设置头部(尾部)View的方式

  • 原始方式:
//复写getItemViewType方法,返回不同的iType值(与onCreateViewHolder保持一致)

        @Override 
        public int getItemViewType(int position) {
        int iType;
        if (position == 0) {
            iType = HEADVIEW;
        } else {
            iType = ORDINARYVIEW;
        }
            return iType;
        }
        @Override
    //复写onCreateViewHolder方法,根据不同的viewType产生不同的View

          @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          View view;

        if (viewType == HEADVIEW){
        view=LayoutInflater.from(parent.getContext()).
        inflate(R.layout.layout_item_head, null, false);
        } else {
            view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_item, null, false);
        }

        return new MyHolder(view);
        }
    //复写onBindViewHolder方法,这里headView是一个固定的View,仅对普通布局进行bean类设定

        public void onBindViewHolder(MyHolder holder, int position) {
        //除头部外,其余项设置文字内同
        if (position != 0) {
            holder.txtContent.setText(lists.get(position));
            if (position % 2 == 0) {
                holder.txtContent.setBackgroundColor(Color.
                parseColor("#000000"));
                }
            }
        }


关键代码:

//在build.gradle(Module)文件中添加
    compile 'com.bartoszlipinski.recyclerviewheader:library:    1.2.0'
    //相应Activity中调用:
    RecyclerViewHeader header = RecyclerViewHeader.fromXml(
    MainActivity.this,R.layout.ayout_item_head);
    header.attachTo(recyclerView);

注意:

  RecyclerViewHeader必须在RecyclerView设置了LayoutManager之后调用。
目前该库适用于LinearLayoutManager,GridLayoutManager和
StaggeredGridLayoutManager布局的RecyclerViews。
只支持垂直布局LayoutManager

4.RecyclerView为子项添加监听事件

在MyAdapter中对ItemView设定点击事件的监听,通过getAdapterPosition可以获取到当前点击的position,再通过该position可以获取到ArrayList中的Bean对象。代码如下:
public MyHolder(View itemView) {
        super(itemView);
        txtContent = (TextView) itemView. findViewById(
        R.id.txtContent);
        txtTit = (TextView) itemView.findViewById(R.id.txtTit);
        img = (ImageView) itemView.findViewById(R.id.img);
        //监控点击项
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 Log.d("adapter","position: " + 
                 getAdapterPosition()); }
            });
        }
在如果想要将点击事件(点击位置position)暴露给外部的话,可以自定义一个接口,利用回调机制,在onClick中的调用接口中的相应方法即可.对Item添加监听的方式有很多种,修改源码,setOnItem-Touch方法等,在此使用一种最简单的方式去实现。

5.RecyclerView显示不同的布局方式,例如:

  • ①仅有content的Item
  • ②有content又有title的Item
  • ③有img,content,title的Item

Bean类设计如下:

public class DataBean {

    public static final int DATA_TYPE_CONTENT = 1;
    public static final int DATA_TYPE_TIT = 2;
    public static final int DATA_TYPE_IMG = 3;

    int iType = DATA_TYPE_IMG;

    String strTit = "";
    String strContent = "";
    String strImgSource = "";

    public DataBean(String _strContext) {
        setType(DATA_TYPE_CONTENT);
        setContent(_strContext);
    }

    public DataBean(String _strTit, String _strContext) {
        this(_strContext);
        setType(DATA_TYPE_TIT);
        setTit(_strTit);
    }

    public DataBean(String strTit, String strContext, String _strImgSource) {
        this(strTit, strContext);
        setType(DATA_TYPE_IMG);
        setImgSource(_strImgSource);
    }

    public void setTit(String strTit) {
        this.strTit = strTit;
    }

    public String getTit() {
        return strTit;
    }

    public void setType(int iType) {
        this.iType = iType;
    }

    public int getType() {
        return iType;
    }

    public void setContent(String strContent) {
        this.strContent = strContent;
    }

    public String getContent() {
        return strContent;
    }

    public void setImgSource(String strImgSource) {
        this.strImgSource = strImgSource;
    }

    public String getImgSource() {
            return strImgSource;
        }
    }

MyAdapter中进行复写getItemViewType方法,根据Bean中的type来确定Item的type值:

public int getItemViewType(int position) {
        DataBean data = datalists.get(position);
        return  data.getType();
    }

同时需要对onCreateViewHolder方法进行修改(根据viewType的值来加载不同的布局文件),核心代码如下

switch (viewType){
            case DataBean.DATA_TYPE_CONTENT:
                iItemView = R.layout.layout_item_content;
                break;
            case DataBean.DATA_TYPE_TIT:
                iItemView = R.layout.layout_item_title;
                break;
            case DataBean.DATA_TYPE_IMG:
                iItemView = R.layout.layout_item_img;
                break;
            default:
                break;
        }
        view = LayoutInflater.from(parent.getContext()).inflate(
                iItemView, null, false);

        return new MyHolder(view);

更改绑定数据的方法onBindViewHolder,注意在onBindViewHolder方法中没有onCreateViewHolder方法中的viewType参数,所以需要根据position在ArrayList中获取相应的元素,再通过Bean类中的getType来确定需要绑定数据的种类。核心代码如下

DataBean _data = datalists.get(position);

        switch (_data.getType()){
            case DataBean.DATA_TYPE_CONTENT:
                if (holder.txtContent != null) {
                    holder.txtContent.setText(_data.getContent());
                }
                break;
            case DataBean.DATA_TYPE_TIT:
                if(holder.txtContent != null){
                    holder.txtContent.setText(_data.getContent());
                }
                if(holder.txtTit != null){
                    holder.txtTit.setText(_data.getTit());
                }
                break;
            case DataBean.DATA_TYPE_IMG:
                if(holder.txtContent != null){
                    holder.txtContent.setText(_data.getContent());
                }
                                if(holder.txtTit != null){
                    holder.txtTit.setText(_data.getTit());
                }
                if(holder.img != null){
                    holder.img.setBackgroundColor(Color.GREEN);
                }
                break;
        }

方便期间,在这里没有实际为ImageView加载真实的图片,仅仅设定了控件的背景色代表设置图片的操作。

6.RecyclerrView设定分割线

官方没有提供设置分割线的方法recyclerView.addItemDecoration()
遗憾的是分割线是一个虚拟类,需要我们自行继承并去实现分割线的显示样式

参考万能的分割线:

完整RecycleViewDivider代码如下

public class RecycleViewDivider extends RecyclerView.ItemDecoration {

    private Paint mPaint;
    private Drawable mDivider;
    private int mDividerHeight = 2;//分割线高度,默认为1px
    private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

    /**
     * 默认分割线:高度为2px,颜色为灰色
     *
     * @param context
     * @param orientation 列表方向
     */
    public RecycleViewDivider(Context context, int orientation) {
        if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
            throw new IllegalArgumentException("请输入正确的参数!");
        }
        mOrientation = orientation;

        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    /**
     * 自定义分割线
     *
     * @param context
     * @param orientation 列表方向
     * @param drawableId  分割线图片
     */
    public RecycleViewDivider(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 RecycleViewDivider(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);
    }


    //获取分割线尺寸
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.set(0, 0, 0, mDividerHeight);
    }

    //绘制分割线
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    //绘制横向 item 分割线
    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + layoutParams.bottomMargin;
            final int bottom = top + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }

    //绘制纵向 item 分割线
    private void drawVertical(Canvas canvas, RecyclerView parent)   {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + layoutParams.rightMargin;
            final int right = left + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
                }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }  
    }

3种使用方式:

//自定义分割线高,指定分割线颜色
        /*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
                LinearLayoutManager.HORIZONTAL,10, Color.BLUE));
        */

        //指定样式(在shape中进行颜色,线高的设置)的分割线
        /*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
                LinearLayoutManager.HORIZONTAL, R.drawable.shape_item_line));*/

        //默认样式实现分割线
        recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,LinearLayoutManager.HORIZONTAL));

drawable/shape_item_line.xml代码如下

<gradient
    android:centerColor="#ff00ff00"
    android:endColor="#ff0000ff"
    android:startColor="#ffff0000"
    android:type="linear" />
<size android:height="4dp"/>