profile image

L o a d i n g . . .

반응형

안드로이드 코틀린 GridLayoutManager spanSizeLookup 이용하기

GridLayoutManager centerHorizontal

 

안드로이드에는 격자레이아웃을 기본으로 제공해 주는데 Recyclerview 에도 격자를 제공해 준다. 이는 주어진 카운터만큼 알아서 자리를 차지해 뷰를 그려주고 나머지는 바로 아래에 같은 방법으로 그려준다.

 

그리고 각 라인마다 혹은 주어진 카운터 마다 위치를 위치를 바꿀 수 있는데 이는 spanSizeLookup 을 이용해야 한다.

 

일단 나는 아래 이미지와 같은 형식의 Gridlayout을 원했다.

마지막 나머지가 2개일 때는 2개가 가운데로, 1개일 때는 1개가 가운데로 오기를 원했다.

Recyclerview이며 layoutmanager은 GridLayoutManger을 사용하였다.

val lm = GridLayoutManager(activity, 6)
lm.spanSizeLookup = object :SpanSizeLookup() {
                override fun getSpanSize(position: Int): Int {
                    val span = listSize % 3
                    return if (listSize < 2) {
                        6
                    } else if (span == 0 || (position <= ((listSize - 1) - span))) {
                        2
                    } else if (span == 1) {
                        6
                    } else {
                        3
                    }
                }
            }                    

기본으로 칸은 3칸이 아닌 6칸으로 만들어야 한다 -> GridLayoutManager(activity, 6)

그래야 2개이거나 1개일 때 가운데로 올 수 있다.

위 조건문에 맞게 return이 6은 1개의 view가 위에서 말한 6칸 모두 차지한다는 것이며,

2는 6칸중 2칸을 차지, 3은 6칸 중 3칸을 차지한다는 것이다.

결국 각 행에서 6은 1개, 3은 2개, 2은 3개를 의미한다.

이렇게 코딩을 하고도 제대로 원하는 형태로 나오지 않을 경우 itemView을 보도록 하자, 가장 상위의 레이아웃이 wrap_content로 되어 있을 경우 제대로 안되는 경우가 있으므로 match_parent로 바꾸면 제대로 나올 것이다.

 

그래도 2개 일때 가운대로 오지만 원하는 위치가 아닐 경우에는, Deco을 사용하면 될 거라 생각이 되지만, 막상 Deco로 값을 주게 되면 해당 아이템 뷰가 사라지는 현상을 볼 수 있다.

 

해결방법으로는 무식하지만 viewHolder에서 해당 포지션을 구해서 직접 레이아웃을 바꾸는 방법밖에 떠오르지 않았다.

if (position == lastPosition) {
            view.setPadding(0, 0, previousLastPositionPadding, 0)
        } else if (position == previousLastPosition) {
            view.setPadding(previousLastPositionPadding, 0, 0, 0)
        }

이거 절대 좋은 방법이라고는 생각이 들지 않지만,, 마지막 아이템이 2개일 경우 이에 해당하는 아이템들만 좌우에 패딩을 넣어 더 가운데로 오게 하였다.

다시 말하지만 위 방법은 그렇게 좋은 방법이라고는 생각이 들지 않는다. 그래도 굳이 구태여 꼭 해야한다면 참고정도 하면 좋겠다.

반응형
복사했습니다!