您的位置:首页 > 移动开发 > Android开发

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

2016-12-24 16:10 513 查看
上篇Android RecyclerView 详解(1)—线性布局

记录了下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);
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. 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();
}


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>


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;
}
}
}


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);
}
}
}
}


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);
}
}
}


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>


未完待续……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: