RecyclerView.ItemDecoration 에서 onDraw 를 이용하여 직접 아이템에 대해 그리는 방법
아래와 같은 GridLayout 을 만들려고 한다.
고려해야할점
- 각 아이템 항목마다 회색 Stroke
- 맨왼쪽 아이템은 왼쪽에 뚫려져 있음 + 맨 오른쪽 아이템은 오른쪽이 뚫려져 있음
- 단순히 하나의 아이템 레이아웃에 사각형의 Stroke를 background로 지정하면 중간선들이 겹쳐보이는 현상이 있음
- Stroke만큼의 padding 을 줘야함
- RecyclerViewAdapter의 onBindViewHolder에서 맨 왼쪽과 맨 오른쪽인 경우 View를 숨겨야함
cf) 숨기는 코드 Sample
override fun onBindViewHolder(holder: BaseViewHolder<CommentUiModel>, position: Int) {
super.onBindViewHolder(holder, position)
if (getItem(position) is CommentUiModel.Sub && getItem(position + 1) is CommentUiModel.Base) {
DataBindingUtil.bind<ItemPostNestedReplyBinding>(holder.itemView)?.apply {
viewBottom.visibility = View.VISIBLE
}
}
if (getItem(position) is CommentUiModel.Base && getItem(position + 1) is CommentUiModel.Sub) {
DataBindingUtil.bind<ItemPostReplyBinding>(holder.itemView)?.apply {
viewBottom.visibility = View.INVISIBLE
}
}
}
-> View를 숨겨야하는 경우 때문에 background로 지정하는것을 포기하고 네모 선들을 각각 View로써 만들어야하는..
( 까다로운 작업이 될것같다.. 더쉬운 방법을 찾아보자)
어떻게 그릴것인가?
1. 각 아이템들에 대해 하단 라인을 먼저 그린다 ( 모든 아이템들이 가지고있는 공통 요소)
2. 맨 오른쪽에 있지 않은 아이템들은 오른쪽 라인을 그린다
3. 맨 위쪽에 있는 아이템들에 대해 위쪽 라인을 그린다
private class GridGuidelineDecoration(
strokeWidth: Int,
@ColorRes
private val lineColorResId: Int
) : RecyclerView.ItemDecoration() {
private val pxStrokeWidth: Float = strokeWidth.pxFromDp
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val spanCount = (parent.layoutManager as GridLayoutManager).spanCount
val paint = Paint().apply {
this.isAntiAlias = true
this.color = ContextCompat.getColor(parent.context, lineColorResId)
this.strokeWidth = pxStrokeWidth
this.style = Paint.Style.STROKE
}
parent.children.forEach { itemView ->
val position = parent.getChildAdapterPosition(itemView)
val spanIndex = (itemView.layoutParams as GridLayoutManager.LayoutParams).spanIndex
val lineIndex = position / spanCount
// 1. 각 아이템들에 대해 하단 라인을 먼저 그린다 ( 모든 아이템들이 가지고있는 공통 요소)
c.drawLine(
itemView.left.toFloat(),
itemView.bottom.toFloat(),
itemView.right.toFloat(),
itemView.bottom.toFloat(),
paint
)
// 2. 맨 오른쪽에 있지 않은 아이템들은 오른쪽 라인을 그린다
if (spanIndex != spanCount - 1) {
c.drawLine(
itemView.right.toFloat(),
itemView.top.toFloat(),
itemView.right.toFloat(),
itemView.bottom.toFloat(),
paint
)
}
// 3. 맨 위쪽에 있는 아이템들에 대해 위쪽 라인을 그린다
if (lineIndex == 0) {
c.drawLine(
itemView.left.toFloat(),
itemView.top.toFloat(),
itemView.right.toFloat(),
itemView.top.toFloat(),
paint
)
}
}
}
}
'Android' 카테고리의 다른 글
데이터 조작 : flatMap 활용하기 (0) | 2021.08.09 |
---|---|
[Refactoring] 여러개의 CheckBox -> Rx 핸들링 (0) | 2021.08.05 |
TroubleShooting With AppbarLayout expand (0) | 2021.06.06 |
상품리스트 - 좋아요 - 툴팁 - 트러블 슈팅 (0) | 2021.06.05 |
비동기 함수 - Rx로 변경하기 (0) | 2021.05.14 |