Android RecyclerView 详解(2)---网格布局(支持多种分割线)

来源:互联网 发布:修改 nginx的 变量 编辑:程序博客网 时间:2024/06/05 09:00

转载地址:http://blog.csdn.net/u010784887/article/details/53860231

上篇Android RecyclerView 详解(1)—线性布局 
记录了下RecyclerView的使用方法,并且讲述了线性布局列表的使用方法,在此基础上加上了万能分割线,支持颜色分割线和图片分割线,同时支持对分割线设置线宽。 
这篇是总结一下网格布局的使用,同样也支持两种分割线和线宽的设置。

主要的相关类:

1. RecyclerView.Adapter

2. GridLayoutManager 网格布局管理器

3. RecycleView.ItemDecoration 分割线

下面就直接通过一个例子来展示:

先上效果图:

(1) 颜色分割线

这里写图片描述

看起来还不错吧,根据item的数量去显示格子,当然如果你需要的样式不是三列,这个很简单,只需要在设置 
GridLayoutManager的时候设置相应的列数即可,即:

mManagerLayout = new GridLayoutManager(getActivity(), 3);
  • 1

(2) 图片分割线

这里写图片描述

可能有人会说你的列表四周都有分割线,其实在不做特殊处理时左边和上面默认是没有分割线的。后面我会加上四周没有分割线的,其实这两种形式在实际开发中都是常见的,先来看四周都有边线的。

由于RecycleView是高度解耦的控件,绘制分割线只和 RecycleView.ItemDecoration 有关,所以我们只需关心怎么去继承 RecycleView.ItemDecoration 去实现我们所需的分割线,如下:

这里需要说明的是:颜色分割线和图片分割线原理是完全一样的,图片分割线只是将一张很细的图片传入即可。

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) {        // 这里传入的parent是recycleview,通过它我们可以获取列表的所有的元素,        // 这里我们遍历列表中的每一个元素,对每一个元素绘制垂直分割线        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            //获取当前item布局参数,通过它可以知道该item的精确位置,我们通过这个位置去绘制它的分割线            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);            }        }    }    //....水平分割线与垂直分割线类似,完整代码见下。}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

下面是完整代码:

1. MainActivity

public class MainActivity extends AppCompatActivity {    private GridFragment mGridFragment;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //网格        mGridFragment = new GridFragment();        getFragmentManager().beginTransaction().replace(R.id.activity_main, mGridFragment).commit();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

activity_main

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"></FrameLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. GridFragment

public class GridFragment extends Fragment implements View.OnClickListener{    private RecyclerView mRecycleViewDrawable;    private RecyclerView mRecycleViewColor;    private LinearLayoutManager mManagerColor;    private LinearLayoutManager mManagerDrawable;    private List<String> mData;    private Button mDrawable;    private Button mColor;    private MyRecycleViewAdapter mRecycleViewAdapter;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_grid_layout, container, false);        mRecycleViewDrawable = (RecyclerView) view.findViewById(R.id.recycleview_drawable);        mRecycleViewColor = (RecyclerView) view.findViewById(R.id.recycleview_color);        mDrawable = (Button) view.findViewById(R.id.btn_drawable);        mDrawable.setOnClickListener(this);        mColor = (Button) view.findViewById(R.id.btn_color);        mColor.setOnClickListener(this);        //设置颜色分割线        mManagerColor = new GridLayoutManager(getActivity(), 3);        mRecycleViewColor.setLayoutManager(mManagerColor);        mRecycleViewColor.addItemDecoration(new GridDivider(getActivity(), 20, this.getResources().getColor(R.color.colorAccent)));        //设置图片分割线        mManagerDrawable = new GridLayoutManager(getActivity(), 3);        mRecycleViewDrawable.setLayoutManager(mManagerDrawable);        Drawable drawable = ContextCompat.getDrawable(getActivity(), R.mipmap.divider);        mRecycleViewDrawable.addItemDecoration(new GridDivider(getActivity(), 20, drawable));        //初始化数据        mData = new ArrayList<String>();        initData(mData);        mRecycleViewAdapter = new MyRecycleViewAdapter(getActivity(), R.layout.item_grid_recycleview, mData);        mRecycleViewColor.setAdapter(mRecycleViewAdapter);        mRecycleViewDrawable.setAdapter(mRecycleViewAdapter);        return view;    }    private void initData(List<String> dataList) {        for (int i = 0; i < 16; i++) {            dataList.add("item" + i);        }    }    @Override    public void onClick(View view) {        int id = view.getId();        switch (id){            case R.id.btn_drawable:                mRecycleViewColor.setVisibility(View.INVISIBLE);                mRecycleViewDrawable.setVisibility(View.VISIBLE);                break;            case R.id.btn_color:                mRecycleViewColor.setVisibility(View.VISIBLE);                mRecycleViewDrawable.setVisibility(View.INVISIBLE);                break;        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

3.分割线 GridDivider

直接继承 RecyclerView.ItemDecoration

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);            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

4. Adapter

public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyRecycleViewAdapter.MyViewHolder> {    private LayoutInflater mLayoutInflater;    private List<String> mDataList;    private int mItemLayout;    public MyRecycleViewAdapter(Context context, int itemLayout, List<String> datalist) {        mLayoutInflater = LayoutInflater.from(context);        mItemLayout = itemLayout;        mDataList = datalist;    }    @Override    public MyRecycleViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        return new MyViewHolder(mLayoutInflater.inflate(mItemLayout, parent, false));    }    @Override    public void onBindViewHolder(MyRecycleViewAdapter.MyViewHolder holder, int position) {        holder.mTextView.setText(mDataList.get(position));    }    @Override    public int getItemCount() {        return mDataList.size();    }    class MyViewHolder extends RecyclerView.ViewHolder {        private TextView mTextView;        public MyViewHolder(View itemView) {            super(itemView);            mTextView = (TextView) itemView.findViewById(R.id.tv);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

adapter 的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"        android:gravity="center"        android:layout_width="match_parent"        android:layout_height="60dp"/></FrameLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

未完待续……