AndroidRecyclerView⽹格布局(⽀持多种分割线)详解
(2)
上篇
记录了下RecyclerView的使⽤⽅法,并且讲述了线性布局列表的使⽤⽅法,在此基础上加上了万能分割线,⽀持颜⾊分割线和图⽚分割线,同时⽀持对分割线设置线宽。
这篇是总结⼀下⽹格布局的使⽤,同样也⽀持两种分割线和线宽的设置。
主要的相关类:
1. RecyclerView.Adapter
2. GridLayoutManager ⽹格布局管理器
3. RecycleView.ItemDecoration 分割线
下⾯就直接通过⼀个例⼦来展⽰:
先上效果图:
(1) 颜⾊分割线
看起来还不错吧,根据item的数量去显⽰格⼦,当然如果你需要的样式不是三列,这个很简单,只需要在设置GridLayoutManager的时候设置相应的列数即可,即:
mManagerLayout = new GridLayoutManager(getActivity(), 3);
(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);
}
/*
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) {
//画⽔平和垂直分割线
drawHorizontalDivider(c, parent);
drawVerticalDivider(c, parent);
}
public void drawVerticalDivider(Canvas c, RecyclerView parent) {
// 这⾥传⼊的parent是recycleview,通过它我们可以获取列表的所有的元素,
// 这⾥我们遍历列表中的每⼀个元素,对每⼀个元素绘制垂直分割线
final int childCount = ChildCount();
for (int i = 0; i < childCount; i++) {
final View child = ChildAt(i);
//获取当前item布局参数,通过它可以知道该item的精确位置,我们通过这个位置去绘制它的分割线  final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) LayoutParams();  final int top = Top() - pMargin;
final int bottom = Bottom() + params.bottomMargin;
int left = 0;
int right = 0;
//左边第⼀列,
if ((i % 3) == 0) {
//item左边分割线
left = Left();
right = left + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {//如果是颜⾊分割线
c.drawRect(left, top, right, bottom, mColorPaint);
}
/
/item右边分割线
left = Right() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
} else {
//⾮左边第⼀列
left = Right() + 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);
}
}
}
android layout布局//....⽔平分割线与垂直分割线类似,完整代码见下。
}
下⾯是完整代码:
1. MainActivity
public class MainActivity extends AppCompatActivity {
private GridFragment mGridFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
//⽹格
mGridFragment = new GridFragment();
getFragmentManager().beginTransaction().replace(R.id.activity_main, mGridFragment)mit(); }
activity_main
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="schemas.android/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
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(leview_drawable);
mRecycleViewColor = (RecyclerView) view.findViewById(leview_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, Resources().lorAccent)));  //设置图⽚分割线
mManagerDrawable = new GridLayoutManager(getActivity(), 3);
mRecycleViewDrawable.setLayoutManager(mManagerDrawable);
Drawable drawable = Drawable(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 = Id();
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;
}
}
}
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);
}
/*
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) {
//画⽔平和垂直分割线
drawHorizontalDivider(c, parent);
drawVerticalDivider(c, parent);
}
public void drawVerticalDivider(Canvas c, RecyclerView parent) {
final int childCount = ChildCount();
for (int i = 0; i < childCount; i++) {
final View child = ChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) LayoutParams();  final int top = Top() - pMargin;
final int bottom = Bottom() + params.bottomMargin;
int left = 0;
int right = 0;
//左边第⼀列
if ((i % 3) == 0) {
//item左边分割线
left = Left();
right = left + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
//item右边分割线
left = Right() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
} else {
//⾮左边第⼀列
left = Right() + 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);
}