Android 여러 View Holder, SpanSize로 만들 때 Item Decoration

11922 단어 ItemDecorationAndroid

ViewType, SpanSize 및 공백


RecryclearView는 ViewType과 SpanSize를 조합하여 여러 ViewHolder(viewHolder와 Adapter가 복잡해짐)를 각각 크기로 표시할 수 있습니다.
이 때 표시되는 View의 공백 (가로 세로 양쪽 사이의 공백) 을 일치시키기 위해서, 모든 ViewHolder에 Margin을 추가하여position에 따라 표시/숨기기를 전환하는 것이 아니라 RecyclearView입니다.ItemDecoration으로 공백을 넣어봤어요.

ItemDecoration의 공백을 기준으로 합니다.



GridDecorationLayoutManager.kt
/**
 * 1,2,3カラムの [RecyclerView.ViewHolder] を表示する [GridLayoutManager]
 */
class GridDecorationLayoutManager(context: Context, val adapter: GridItemAdapter)
    : GridLayoutManager(context, 6, GridLayout.VERTICAL, false) {

    init {
        spanSizeLookup = object : SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                // 1カラム→6, 2カラム→3, 3カラム→2
                return adapter.getSpanSize(position)
            }
        }
    }
}
GridItemDecoration.kt
/**
 * [RecyclerView.ViewHolder] とSpanSizeによって余白を分ける [RecyclerView.ItemDecoration]
 */
class GridItemDecoration(context: Context) : RecyclerView.ItemDecoration() {

    private val margin = context.resources.getDimensionPixelSize(R.dimen.grid_decoration_margin)

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val params = view.layoutParams as? GridLayoutManager.LayoutParams
        val manager = parent.layoutManager as? GridLayoutManager
        val spanIndex = params?.spanIndex ?: 0
        val spanSize = params?.spanSize ?: 1
        val spanCount = manager?.spanCount ?: 1

        val isTop = parent.getChildAdapterPosition(view) == 0
        val isStart = spanIndex == 0
        val isEnd = spanIndex + spanSize == spanCount

        when (parent.findContainingViewHolder(view)) {
            is LargeViewHolder -> {
                // 1カラムで表示するViewHolder、最上部のとき上方向に余白をつける
                outRect.set(margin, if (isTop) margin else 0, margin, margin)
            }
            is MediumViewHolder -> {
                // 2カラムで表示するViewHolder、最上部のとき上方向に余白をつける、端かどうかで余白を変える
                outRect.set(
                        if (isStart) margin else margin / 2,
                        if (isTop) margin else 0,
                        if (isEnd) margin else margin / 2,
                        margin)
            }
            is SmallViewHolder -> {
                // 3カラムで表示するViewHolder、最上部のとき上方向に余白をつける、端かどうかで余白を変える
                outRect.set(
                        if (isStart) margin else if (isEnd) margin / 3 else margin * 2 / 3,
                        if (isTop) margin else 0,
                        if (isStart) margin / 3 else if (isEnd) margin else margin * 2 / 3,
                        margin)
            }
        }
    }
}

양쪽 끝에 따라 공백을 바꿀 필요가 있습니까?


위 ItemDecoration에서 끝(세로 Grid LayoutManager의 경우 2~3열의 가장 왼쪽과 가장 오른쪽)의 ViewHolder가 좌우 공백을 바꿨지만, 조사 결과 발견된 실시례 중 왼쪽에만 좌우 공백을 바꾼 경우도 있었다.
예를 들어 왼쪽 왼쪽에만 공백을 남기고 왼쪽 이외에 오른쪽에 공백을 두면 다음과 같다. ViewHolder의 디스플레이 사이즈가 다르기 때문에 각 ViewHolder는 같은 크기의 공백이 필요할 것 같다.

https://stackoverflow.com/questions/30524599/items-are-not-the-same-width-when-using-recyclerview-gridlayoutmanager-to-make-c

총결산

  • Item Decoration으로 공백 추가 가능
  • 페이지 간격을 동일하게 하지 않으면 ViewHolder의 디스플레이 사이즈가 바뀌어 고통스러워요. 어떡하지
  • Item Decoration과 ViewHolder로 각각 공백을 더합니까?
  • Recrycle이 뭐냐면요.

    좋은 웹페이지 즐겨찾기