출처: https://mparchive.tistory.com/214
수 요소
여기서 여러 메소드 들에서 firstChild 혹은 lastChild를 getChildAt(0)과 getChildAt(childCount -1)로 각각 호출하는 부분이 있는데, 이는 현재 RecyclerView에 실제로 붙어 있는 item들의 맨 첫 아이템, 그리고 가장 마지막 아이템을 참고하는 것임을 주의하자.
1. generateDefaultLayoutParams
RecyclerView의 각 아이템에 적용할 LayoutParams을 지정한다.
override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams =
LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT,
RecyclerView.LayoutParams.WRAP_CONTENT
)
2. onLayoutChildren
Recycler에 보여줄 아이템이 1개 이상인 경우 이를 그리도록 호출되는 메소드이다.
override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
detachAndScrapAttachedViews(recycler)
if (state.itemCount <= 0) return
fillBottom(recycler, state.itemCount)
}
3. fillBottom
최초 설정된 아이템을 그리거나, 아래로 스크롤하는 경우 아이템을 그리는 메소드.
여기서 childCount는 현재 RecyclerView에 실제로 attach된 아이템의 갯수로, RecyclerView Adapter에 설정한 아이템의 갯수와는 다르다.
private fun fillBottom(recycler: RecyclerView.Recycler, adapterItemCount: Int) {
var hardTop: Int
var softTop: Int
var startPosition: Int
if (childCount > 0) {
val lastChild = getChildAt(childCount - 1) ?: return
val lastChildPosition = getPosition(lastChild)
startPosition = lastChildPosition + 1
val lp = lastChild.layoutParams()
// If the item is solid the hard line is moved down to bottom of this view minus allowed overlap
// If not solid then the hard line is moved down to top of this item
hardTop =
if (lp.isSolid) {
getDecoratedBottom(lastChild) + lp.bottomMargin - ((lastChild.measuredHeight + lp.verticalMargin) * lp.verticalOverlay).toInt()
} else {
getDecoratedTop(lastChild)
}
// Soft line is always moved to the bottom of given item
softTop = getDecoratedBottom(lastChild) + lp.bottomMargin
} else {
// If there are no attached child views then we start from the top of parent view
hardTop = parentTop + if (anchorPosition < adapterItemCount) anchorOffset else 0
softTop = parentTop + if (anchorPosition < adapterItemCount) anchorOffset else 0
startPosition = if (anchorPosition < adapterItemCount) anchorPosition else 0
}
val availableBottom = if (clipToPadding) parentBottom else height
for (i in startPosition until adapterItemCount) {
if (hardTop > availableBottom) break
val view = recycler.getViewForPosition(i)
addView(view)
view.setBeelineLayoutParams(i)
view.measure()
val lp = view.layoutParams()
if (lp.isSolid) {
// For solid items, the top is determined as the lower one of previous item’s hard line
// or previous item’s soft line minus this view’s vertical overlap allowance
val top = max(
hardTop,
softTop - ((view.measuredHeight + lp.verticalMargin) * lp.verticalOverlay).toInt()
)
val bottom = top + view.measuredHeight + lp.verticalMargin
layoutView(view, top, bottom)
// The hard line is moved down to bottom of this view minus allowed overlap
hardTop = bottom - ((view.measuredHeight + lp.verticalMargin) * lp.verticalOverlay).toInt()
softTop = bottom
} else {
// If the item is not solid then we lay it out according to the current hard line
val top = hardTop
val bottom = top + view.measuredHeight + lp.verticalMargin
layoutView(view, top, bottom)
softTop = bottom
}
}
}
4. fillTop
위로 스크롤 하는 경우 아래에서 위로 아이템을 그려 나가는 메소드.
출처: https://mparchive.tistory.com/214 [My Program Archive:티스토리]
등 ... 출처 참조
반응형
'코딩ㆍ개발 정보 > 안드로이드앱 (코틀린)' 카테고리의 다른 글
리사이클러뷰 에 지정된 item 레이아웃 파일 변경하는 방법 (0) | 2023.12.24 |
---|---|
안드로이드 shape 설정하는 방법 (0) | 2023.12.24 |
Fragment에서 데이터 바인딩 방법 (0) | 2023.12.24 |
안드로이드 코틀린 프로젝트 (복제)사본 만드는 방법 (0) | 2023.09.05 |
안드로이드 스튜디오 빌드 에러 Can't determine type for tag '<macro name="m3_comp_assist_chip_container_shape">?attr/shapeAppearanceCornerSmall</macro>' (0) | 2023.09.03 |
댓글