티스토리 뷰

안드로이드

GridLayoutManager decoration

성현아빠 2024. 7. 19. 08:38

grid layout을 사용해야하는 일이 또 발생했다.

이전에는 항목 여백을 item layout에서 줬었는데

화면 해상도에 따라 이상하게 보이는 경우가 있어 decoration 작업을 이번에 진행하기로 했다.

 

androidx.recyclerview.widget.GridLayoutManager

 

RecyclerView에서 GridLayoutManager 속성을 주고

이 RecyclerView의 크기를 아이템 갯수와 여백 포함한 width 값으로 설정.(center_horizontal 정렬로 가운데 위치)

이 때에 리스트 아이템 layout에서 여백은 포함하지 않는다.

이렇게 하여 리스트를 보면은 여백이 없이 붙어 보인다.

 

그리고 데코레이션에서 spanIndex에 따라 여백을 설정하면 보기좋게 여백을 추가 할 수 있다.

 

해상도가 320 이하인 경우에는 item 크기를 변경해 주고

그 이상인 경우에는 기본 레이아웃에 가운데 정렬로 보여준다.

 

그리고 position인 2번째 줄 부터는 top margin 추가하여 여백에 대한 처리 해결.

 

해상도에 따라 크기나 갯수를 조절 하고 싶지만,

프로젝트 일정에 이런건 비 포함 사항이라

원래 이런것도 안하고 진행했는데, 이번엔 그냥 해줬다.

class AttachFileItemDecoration(private val context: Context, private val displayWidthPx: Int) : RecyclerView.ItemDecoration() {
    private val horizontalMargin = context.resources.getDimensionPixelSize(R.dimen.attach_file_margin_size)

    private fun px2dp(px: Int, context: Context): Int {
        return (px / ((context.resources.displayMetrics.densityDpi.toFloat()) / DisplayMetrics.DENSITY_DEFAULT)).toInt()
    }

    private fun dp2px(context: Context, dp: Int): Int {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), context.resources.displayMetrics).toInt()
    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)

        val spanIndex = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
        val position = parent.getChildAdapterPosition(view)

        outRect.run {
            when (px2dp(displayWidthPx, context)) {
                in 1..320 -> {
                    val size = (displayWidthPx - dp2px(context, 40) - dp2px(context, 12)) / 4
                    Log.d("테스트", "***** width = $size")
                    (view.layoutParams as GridLayoutManager.LayoutParams).width = size
                    (view.layoutParams as GridLayoutManager.LayoutParams).height = size
                }
                else -> {
                }
            }

            // setting left / right margin
            if (parent.getChildViewHolder(view) is AttachFileListAdapter.AttachFileItemViewHolder) {
                when (spanIndex % 4) {
                    0 -> {
                        left = 0
                        right = horizontalMargin
                    }
                    1 -> {
                        left = 0
                        right = horizontalMargin
                    }
                    2 -> {
                        left = 0
                        right = horizontalMargin
                    }
                    3 -> {
                        left = 0
                        right = 0
                    }
                }
            }

            // setting top margin (2 line start)
            if (position > 3) {
                top = horizontalMargin
            }
        }
    }
}

 

 

Decoration 적용한 결과물

 

'안드로이드' 카테고리의 다른 글

application restart  (0) 2024.04.12
BuildConfig setting change  (0) 2024.02.22
Notification sound 재생  (0) 2023.12.12
앱 알림 설정 값 가져오기  (0) 2023.12.12
인앱 업데이트  (0) 2022.11.25