[Android/Kotlin] RecyclerView 구분선, 아이템 간격 Decoration
안녕하세요 골드입니다.
오늘은 리사이클러뷰를 활용할 때 사용하면 좋은 Decoration에 대해서 글을 쓰도록 하겠습니다.
XML에서 Margin 설정하고 구분선 View를 그리지 않고 Decoration을 사용하는 이유.
- Decoration을 사용하면 아이템 index별로 간격을 설정할 수 있습니다. 이렇게 하면 0번째 아이템과 마지막 아이템의 간격이 미묘하게 다르게 생성되는 문제를 해결할 수 있습니다.
- XML에서 정의하는 구분선과 Decoration에서 그리는 View는 성능 차이가 있습니다. XML에서 뷰를 그리는 작업이 더 무거운데, 리사이클러뷰를 선언하여 리스트를 불러올 땐 단순히 낱개의 아이템을 불러오지 않고 대량의 아이템을 불러오기 때문에 이는 작지 않은 차이를 만들어 냅니다.
RecyclerView Decoration을 사용하는 이유를 알아보았습니다. 이제 class를 작성하도록 하겠습니다. 앞으로 바뀌게 될 리사이클러뷰의 초기 모습입니다.
RecyclerView.ItemDecoration() 상속
먼저 ItemDecoration 클래스를 상속받습니다. 해당 클래스 블럭 안에서 Control + O를 누르면 오버라이드 메서드 목록이 나옵니다. 그중 getItemOffsets 함수를 선택합니다. 이 함수는 리사이클러뷰 아이템의 간격을 설정할 수 있도록 도와줍니다.
getItemOffsets 함수의 매개변수로 아이템 테두리, 데코레이트할 자식 뷰, 해당 데코레이션 클래스를 추가한 리사이클러뷰, 현재 리사이클러뷰의 상태가 있습니다.
- position 변수를 구하기 위해 사용한 코드는 이렇습니다. parent(리사이클러뷰)의 Adapter 안에 들어있는 자식(view)들의 위치 값을 가져옵니다.
- count는 리사이클러뷰의 total item count를 불러옵니다.
if문 코드가 썩 마음에 들지 않지만 저런 식으로 특정 position에 위치한 자식 뷰들을 데코레이트 할 수 있습니다. 저는 20만큼 위아래 간격을 추가하였습니다.
다음은 구분선입니다. 만약 구분선만 추가하고 싶은 경우 DividerItemDecoration을 사용할 수도 있습니다. 구분선을 추가하기 위한 기본형 Decoration입니다. 그러나 만약 커스텀 하고 싶다면 onDraw() 혹은 onDrawOver() 함수를 오버라이드 해야 합니다. 둘의 차이는 뷰를 그리는 순서에 있습니다. onDrawOver()는 리사이클러뷰 아이템 뷰를 모두 그린 후에 그 위에 그려집니다.
onDraw() 답게 Canvas 객체가 있습니다. 뷰를 그릴땐 반드시 Canvas 객체가 필요합니다. Paint 객체를 생성해서 간단하게 색상을 지정하고 긴 직사각형을 그리기 위해 상하좌우 변수를 모두 구합니다. 좌우를 구하는 이유는 구분선의 넓이를 위하기 위함이기 때문에 공통부분으로 for문 밖에 선언했고 이외에 변수들은 모두 for문 안에 있습니다.
구분선까지 생긴 모습입니다.
여기까지 골드였습니다.
감사합니다.