본문

ItemDecoration 개념 및 실습

도입

이번 포스팅에서는 RecyclerView의 ItemDecoration에 대해 정리할 예정이다.


개념

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ItemDecoration

ItemDecoration 클래스는 RecyclerView 내부에 있는 추상 클래스이다.

이름처럼 RecyclerView의 아이템들을 꾸미는 역할을 한다.

그 중에서도 유용한 것은 RecyclerView 내의 아이템이나 그룹들 간의 `구분자(divider)`를 설정할 수 있다.

 

내부함수

1. onDraw

공식문서의 설명 처럼 해당 함수는 recyclerView의 아이템이 그려지기 전에 호출되므로 아이템보다 아래 위치하게 된다.
아이템 때문에 가려져 안보일 수도 있다.

2. onDrawOver

공식문서의 설명처럼 해당 함수는 recyclerView의 아이템 그려진 후에 호출되므로 아이템보다 위에 위치하게 된다.
아이템 때문에 가려지는 일은 없지만 아이템을 가릴 수 있다.

3. getItemOffsets

RecyclerView의 measureChild 성격의 메소드들을 통해 호출되며 커스텀하게 getItemOffset를 구현하지 않는다면 크기가 없는 rect을 반환해 아무런 동작을 하지 않는다.
그래서 아이템 간의 구분자를 설정하기 위해서는 해당 메소드를 오버라이딩해 rect을 설정해주면 된다.


실습

Step1. ItemDecoration을 상속 

1
2
3
4
5
6
7
8
9
class CustomDecoration(
    private val dividerHeight: Int,
    private val dividerColor: Int = Color.TRANSPARENT
) : RecyclerView.ItemDecoration() {
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        drawDivider(c, parent, color = Color.RED)
    }
    //...
}
cs

Step2. drawDivider 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private fun drawDivider(
    c: Canvas,
    recyclerView: RecyclerView,
    color: Int
) {
    paint.color = color
    for (i in 0 until recyclerView.childCount) {
        val child = recyclerView.getChildAt(i)
        val param = child.layoutParams as RecyclerView.LayoutParams
 
        val dividerTop = child.bottom + param.bottomMargin
        val dividerBottom = dividerTop + dividerHeight
 
        c.drawRect(
            child.left.toFloat(),
            dividerTop.toFloat(),
            child.right.toFloat(),
            dividerBottom.toFloat(),
            paint
        )
    }
}
cs

Step3. getOffsets 함수 구현

1
2
3
4
5
6
7
8
override fun getItemOffsets(
    outRect: Rect,
    view: View,
    parent: RecyclerView,
    state: RecyclerView.State
) {
    outRect.top = dividerHeight
}
cs

스크린 샷


진행하면 궁금했던 점

1. onDraw, onDrawOver를 동시에 구현하면 어떻게 될까? 

둘다 설정 (생각해보면 당연한 것)

2. getOffsets를 구현하지 않는다면? 

따로 divider 영역이 설정되지 않고 item 아래 or 위에 draw된다.

 

 

#recyclerView divider #itemDecoration #recyclerView 구분자

공유

댓글