一 添加分割线
less
recyclerView.addItemDecoration(DividerItemDecoration(this@MainActivity,LinearLayout.VERTICAL))
二 什么是ItemDecoration
它是Item的装饰,在Item的四周,我们可以给它添加上自定义的装饰,我们也可以在Item的上下左右添加装饰,而且这些装饰是允许我们自定义的。如果我们想实现其它的装饰效果,就需要自定义了。
三 自定义ItemDecoration
3.1 getItemOffsets的意义
当我们要重写ItemDecoration时,主要涉及到三个函数
typescript
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
}
首先我们来看看getItemOffsets: 它的主要作用就是给item的四周加上边距,实现的效果类似margin,将item的四周撑开一些距离,在撑开这些距离后,我们将可以利用上面的onDraw函数,在这个距离上进行绘图。我们来看看这个方法
kotlin
verride fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
}
outRect:Rect 就是表示在item的上下左右所撑开的距离。 view:View 是指当前Item的View对象 parent:RecyclerView 是指RecyclerView本身 state:Recycler.State 通过State可以获取当前RecyclerView的状态。
下面我们专门来看看Rect outRect这个参数,outRect的top,left,right,bottom四个点,是指Item上,左,右,下撑开的距离,这个值默认是0。
3.2 getItemOffsets示例 我们自定义一条红色分割线,首先我们给整个布局加上一个红色的背景色。
ini
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F60459"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
然后再给每个Item添加上默认的背景色白色,这样有白色的地方就不会透出背景色的红色了,而没有白色的地方就会露出红色。
ini
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:padding="16dp">
<TextView
android:id="@+id/tvItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"/>
</LinearLayout>
然后就是自定义我们的CustomLinearLayoutDecoration,
kotlin
class CustomLinearLayoutDecoration : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.top = 1 //这里暂时先直接写死1px
}
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
}
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
}
}
效果如图展示:
这里可以看到每个Item的上方都出现了一条红线,如果我们改为底部1px,左侧50px,右侧100px,
kotlin
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
//这里暂时先直接写死1px
outRect.left=50;
outRect.right=100;
outRect.bottom=1;
}
3.3 onDraw的用法:
kotlin
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
}
c:Canvas是指通过getItemOffsets撑开的空白区域所对应的画布,通过这个canvas可以在getItemOffsetes所撑出来的区域进行任意绘图。现在我们想在getItemOffsets的Item的左侧撑出来的200px的距离,然后在中间画一个圆形。
注意:getItemOffsets是针对每个Item走一次,也就是说每个Item的outRect都可以不同,但是onDraw所针对整个ItemDecoration只执行一次,并不是针对Item,所有我们需要在onDraw中绘图时,一次性将所有Item的ItemOration绘制完成。
下面我们来举例每个Item也是可以设置不同的outRect,这点特别适合对第一个item进行特殊处理的情况。
ini
private val LEFT_OFFSETS = 200 //这里暂时先直接写死200px
private val RADIUS = 20f
var mPaint: Paint = Paint().apply {
color = Color.GREEN
}
ini
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
//这里获取itemview位于整个RecyclerView列表的position
val position = parent.getChildAdapterPosition(view)
if (position == 0) {
outRect.left = 400;
outRect.bottom = 1;
} else {
outRect.left = LEFT_OFFSETS;
outRect.bottom = 1;
}
}