일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- NavController
- sharedFlow
- DiffUtil
- Android
- Authentication
- Kotlin
- 코틀린
- 파이어베이스
- 코딩테스트
- 플레이스토어
- 클린아키텍처
- 뷰
- XML
- Build variants
- UiState
- 알고리즘
- 컴포즈
- coroutine
- MVVM
- Jetpack
- 리사이클러뷰
- cleanarchitecture
- 회원가입
- Compose
- 커스텀뷰
- NavHost
- Flow
- 로그인
- ListAdapter
- 안드로이드
- Today
- Total
Grusie 안드로이드 개발 기술 블로그
[Android] RecyclerView, ItemDecoration으로 마진 조절하기 본문
디자인을 받아 뷰를 그리던 중, GridLayout을 가진 RecyclerView를 구현해야 했던 상황이었다.
이전에도 이런 적이 있었기에, ItemDecoration을 사용하였으나, 또 다시 찾아보게 되어서 정리를 해두려고 한다.
이번에 그릴 뷰는 사이에 7dp라는 마진이 있고, spanCount가 2인 그리드 뷰이다.
바깥쪽엔 14dp가 아닌, 20dp가 있기에 innerMargin과 outerMargin을 따로 받아 처리하도록한다.
로직
1. 맨 처음 column일 경우는, 왼쪽에 outerMargin / 2, 오른쪽에 innerMargin
2. 마지막 column일 경우는, 왼쪽에 innerMargin / 2, 오른쪽에 outerMargin
3. 나머지 column들은 양쪽에 innerMargin / 2
범용성을 위해, column의 개수와, innerMargin, outerMargin을 받아서 처리하자.
class GridItemDecoration(
private val spanCount: Int,
private val pxInnerSpace: Int = 0,
private val pxOuterSpace: Int = 0
) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val childCount = parent.childCount
if (childCount <= 0) return
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
when (column) {
0 -> { //첫 column
outRect.right = pxInnerSpace/2
outRect.left = pxOuterSpace
}
spanCount - 1 -> { //마지막 column
outRect.right = pxOuterSpace
outRect.left = pxInnerSpace / 2
}
else -> { //다른 column들
outRect.right = pxInnerSpace / 2
outRect.left = pxInnerSpace / 2
}
}
}
}
SpanCount와 innerSpace, outerSpace를 입력 받아, 원하는 로직대로 처리를 해준 후, RecyclerView.ItemDecoration을 리턴한다.
현재 Row에 대한 마진은 처리하지 않았는데, 이는 필자가 받은 디자인에서는 처리할 필요가 없어서이며, 만약 Row에 대한 처리가 필요하다면 그에 대한 처리도 해주어야 할 것이다.
변경되는 점이라고 한다면, column은 %이고, Row는 / 일것이며, position - 1 을 해주고 몫에 + 1을 해주어야 할 것이다.
val row = childCount - 1 / spanCount + 1
childCount가 0이면 안 되기에, 최상단에 0일 경우 return을 적용 해두었다.
원하는 대로 잘 나오는 것을 확인 할 수 있다.
후기
역시나 xml일 경우 이렇게 불편한 점은 있지만, 어떻게든 해낼 수 있다는 점이 참 신기한 것 같다.
다들 같은 고민을 하는 경우가 많아서 더 그런 것 같다.
'안드로이드 개발 > 뷰' 카테고리의 다른 글
[Android] 이미지 축소 확대, 회전 커스텀 뷰 만들기 (feat. 터치 이벤트 종류, 각도 함수) (0) | 2024.04.24 |
---|---|
[Android] BottomSheetDialogFragment 사용하기 (+ 둥근 모서리) (0) | 2024.04.18 |
[Android] 정사각형 뷰 만들기 커스텀뷰, constraint layout_constraintDimensionRatio 속성 (0) | 2024.04.09 |
[Android] Fragment를 newInstance()로 생성해야 하는 이유 (0) | 2024.04.02 |
[Android] lifeCycleScope.launchedWhenCreated, Started, Resumed 대체(deprecated) (0) | 2024.03.26 |