【记录】记录点滴
【需求】简单使用分割线与自定义分割线
1. 利用DividerItemDecoration, 简单实现分割线
2. 基于RecyclerView.ItemDecoration,自定义分割线
在简单使用RecyclerView中,最后实现了个嵌套的界面,一个Linear List嵌套一个Grid。先上最终实现的效果图
其中Grid中的自定义分割线比较细,所以图大些。
1. 利用DividerItemDecoration
在外层的 List 中实现渐变色的布局
先定义个渐变色的shape,作为分割线
<!-- 渐变色的分割线 -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="@android:color/holo_red_light"
android:endColor="@android:color/holo_green_light"/>
<size
android:height="1dp"/>
</shape>
然后在代码中创建DividerItemDecoration实例,并添加到RecyclerView中,如下
...
DividerItemDecoration decoration = new DividerItemDecoration(MultiTypeRecyclerActivity.this, DividerItemDecoration.VERTICAL);
decoration.setDrawable(ContextCompat.getDrawable(this,R.drawable.shape_item_decoration));
recyclerview.addItemDecoration(decoration);
...
到这里,就实现了简单的分割线。
2. 基于RecyclerView.ItemDecoration
DividerItemDecoration实际也是基于RecyclerView.ItemDecoration实现的,从源码中可以看出,它只支持画“水平”或“竖直”的分割线。需要关注的几个方法是:
//画在item的下层,如果和item有重叠部分,会被item的重叠部分掩盖
public void onDraw()
//画在item的上层,如果和item有重叠部分,会覆盖item的重叠部分,并展示
public void onDrawOver()
//item上下左右处的间隔距离
//但不能说这里是设置分割线尺寸的地方
public void getItemOffsets()
先看看这个丑样子,每个item上下左右不仅实现了不同颜色的分割线,还在item的上侧画了条粗的黑色分割线,并在下侧有一条细的黑色分割线(这条分割线实际是画了条粗的,但是被item遮盖了一部分,只展示出一点边缘)。
一步步实现:
1)仔细看,item中间还有灰色,这是因为设置了灰色的背景,并且通过getItemOffsets设置了item间的间距,如下
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//获得View在Recycler中的位置
int position = parent.getChildAdapterPosition(view);
if(position < 3){
//前三个上下左右都是10px间隔
outRect.set(10, 10, 10, 10);
} else {
//其他左侧没有间隔,上下右是10px的间隔,左侧没有间隔
outRect.set(0, 10, 10, 10);
}
}
2)接下来就是画分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
//画在下层
super.onDraw(c, parent, state);
Paint pleft = new Paint();
Paint pright = new Paint();
Paint ptop = new Paint();
Paint pbottom = new Paint();
pleft.setColor(Color.BLUE);
pright.setColor(Color.GREEN);
ptop.setColor(Color.YELLOW);
pbottom.setColor(Color.RED);
Rect rleft = new Rect();
Rect rright = new Rect();
Rect rtop = new Rect();
Rect rbottom = new Rect();
Paint pBack = new Paint();
pBack.setColor(Color.BLACK);
for(int i = 0; i < parent.getChildCount(); i++){
View v = parent.getChildAt(i);
rleft.set(v.getLeft() - 5, v.getTop(), v.getLeft(), v.getBottom());
rright.set(v.getRight(), v.getTop(), v.getRight() + 5, v.getBottom());
rtop.set(v.getLeft(), v.getTop() - 5, v.getRight(), v.getTop());
rbottom.set(v.getLeft(), v.getBottom(), v.getRight(), v.getBottom() + 10);
//上下左右的四条分割线
c.drawRect(rleft, pleft);
c.drawRect(rright, pright);
c.drawRect(rtop, ptop);
c.drawRect(rbottom, pbottom);
//在每个item的下侧画,一条25高的黑色分割线
//但是因为画在下层,被item遮盖了一部分,所以就变成细细的一条
c.drawRect(new Rect(v.getLeft(), v.getBottom() - 20, v.getRight(), v.getBottom() + 5), pBack);
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
//在每个item的上侧画一条黑色分割线,因为画在上层,所以遮盖了item的一部分,并全部展示了出来
super.onDrawOver(c, parent, state);
Paint p = new Paint();
p.setColor(Color.BLACK);
for(int i = 0; i < parent.getChildCount(); i++){
View v = parent.getChildAt(i);
c.drawRect(new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getTop() + 20), p);
}
}
PS:如果考虑下padding时的效果,要在onDraw和onDrawOver中加入代码段
...
//如果RecyclerView的clipToPadding设置了true,则裁剪Canvas,不在padding区域内绘制内容
if (parent.getClipToPadding()) {
int canvasLeft = parent.getPaddingLeft();
int canvasRight = parent.getWidth() - parent.getPaddingRight();
int canvasTop = parent.getPaddingTop();
int canvasBottom = parent.getHeight() - parent.getPaddingBottom();
canvas.clipRect(canvasLeft, canvasTop, canvasRight, canvasBottom);
}
...