Current scope: simple_xml| all classes
|
kr.open.library.simple_ui.xml.ui.adapter.normal.headerfooter
Coverage Summary for Class: HeaderFooterAdapterData (kr.open.library.simple_ui.xml.ui.adapter.normal.headerfooter)
| Class | Method, % | Branch, % | Line, % | Instruction, % |
|---|---|---|---|---|
| HeaderFooterAdapterData | 47.1% (8/17) | 84.2% (16/19) | 58.3% (35/60) | 65.1% (168/258) |
| HeaderFooterAdapterData$WhenMappings | ||||
| Total | 47.1% (8/17) | 84.2% (16/19) | 58.3% (35/60) | 65.1% (168/258) |
package kr.open.library.simple_ui.xml.ui.adapter.normal.headerfooter
import kr.open.library.simple_ui.xml.ui.adapter.normal.base.BaseRcvAdapterData
/**
* Section data store for [HeaderFooterRcvAdapter].<br><br>
* [HeaderFooterRcvAdapter]용 섹션 데이터 저장소입니다.<br>
*
* Extends [BaseRcvAdapterData] to add header and footer sections.<br><br>
* [BaseRcvAdapterData]를 확장해 header와 footer 섹션을 추가합니다.<br>
*/
internal class HeaderFooterAdapterData<ITEM> : BaseRcvAdapterData<ITEM>() {
/**
* Mutable header section items.<br><br>
* header 섹션의 가변 아이템 목록입니다.<br>
*/
internal val headerItems: MutableList<ITEM> = mutableListOf()
/**
* Mutable footer section items.<br><br>
* footer 섹션의 가변 아이템 목록입니다.<br>
*/
internal val footerItems: MutableList<ITEM> = mutableListOf()
/**
* Returns section item for the resolved adapter position.<br><br>
* 해석된 adapter 위치의 섹션 아이템을 반환합니다.<br>
*/
fun getSectionItemOrNull(resolved: HeaderFooterRcvAdapterSectionPosition): ITEM? =
when (resolved.sectionType) {
HeaderFooterRcvAdapterSectionType.HEADER -> headerItems.getOrNull(resolved.sectionPosition)
HeaderFooterRcvAdapterSectionType.CONTENT -> contentItems.getOrNull(resolved.sectionPosition)
HeaderFooterRcvAdapterSectionType.FOOTER -> footerItems.getOrNull(resolved.sectionPosition)
}
/**
* Returns total item count including header, content, and footer.<br><br>
* header, content, footer를 포함한 전체 아이템 수를 반환합니다.<br>
*/
internal override fun getTotalSize(): Int = headerItems.size + contentItems.size + footerItems.size
/**
* Replaces all header items.<br><br>
* 전체 header 아이템을 교체합니다.<br>
*/
internal fun setHeaderItems(items: List<ITEM>) {
headerItems.clear()
headerItems.addAll(items)
}
/**
* Replaces all footer items.<br><br>
* 전체 footer 아이템을 교체합니다.<br>
*/
internal fun setFooterItems(items: List<ITEM>) {
footerItems.clear()
footerItems.addAll(items)
}
/**
* Appends one header item and returns its adapter position.<br><br>
* header 아이템 1개를 추가하고 adapter 위치를 반환합니다.<br>
*/
internal fun addHeaderItem(item: ITEM): Int {
val insertPosition = headerItems.size
headerItems.add(item)
return insertPosition
}
/**
* Inserts one header item at a section position and returns its adapter position.<br><br>
* header 섹션 위치에 아이템을 삽입하고 adapter 위치를 반환합니다.<br>
*/
internal fun addHeaderItemAt(position: Int, item: ITEM): Int {
headerItems.add(position, item)
return position
}
/**
* Appends header items and returns inserted adapter start position.<br><br>
* header 아이템 목록을 추가하고 삽입 시작 adapter 위치를 반환합니다.<br>
*/
internal fun addHeaderItems(items: List<ITEM>): Int {
val insertStart = headerItems.size
headerItems.addAll(items)
return insertStart
}
/**
* Clears all header items and returns removed count.<br><br>
* 전체 header 아이템을 제거하고 제거 개수를 반환합니다.<br>
*/
internal fun clearHeaderItems(): Int {
val removedCount = headerItems.size
headerItems.clear()
return removedCount
}
/**
* Appends one footer item and returns its adapter insert position.<br><br>
* footer 아이템 1개를 추가하고 adapter 삽입 위치를 반환합니다.<br>
*/
internal fun addFooterItem(item: ITEM): Int {
val insertStart = footerToAdapterPosition(footerItems.size)
footerItems.add(item)
return insertStart
}
/**
* Inserts one footer item and returns its adapter insert position.<br><br>
* footer 아이템 1개를 삽입하고 adapter 삽입 위치를 반환합니다.<br>
*/
internal fun addFooterItemAt(position: Int, item: ITEM): Int {
val insertStart = footerToAdapterPosition(position)
footerItems.add(position, item)
return insertStart
}
/**
* Appends footer items and returns inserted adapter start position.<br><br>
* footer 아이템 목록을 추가하고 삽입 시작 adapter 위치를 반환합니다.<br>
*/
internal fun addFooterItems(items: List<ITEM>): Int {
val insertStart = footerToAdapterPosition(footerItems.size)
footerItems.addAll(items)
return insertStart
}
/**
* Clears footer items and returns adapter start position before removal.<br><br>
* footer를 비우기 전 제거 시작 adapter 위치를 반환합니다.<br>
*/
internal fun clearFooterItems(): Int {
val start = footerToAdapterPosition(0)
footerItems.clear()
return start
}
/**
* Converts content section position to adapter position.<br><br>
* content 섹션 위치를 adapter 위치로 변환합니다.<br>
*/
override fun contentToAdapterPosition(contentPosition: Int): Int = headerItems.size + contentPosition
/**
* Converts footer section position to adapter position.<br><br>
* footer 섹션 위치를 adapter 위치로 변환합니다.<br>
*/
internal fun footerToAdapterPosition(footerPosition: Int): Int =
headerItems.size + contentItems.size + footerPosition
/**
* Converts adapter position to content section position when possible.<br><br>
* 가능하면 adapter 위치를 content 섹션 위치로 변환합니다.<br>
*/
internal fun adapterToContentPosition(adapterPosition: Int): Int? {
val contentPosition = adapterPosition - headerItems.size
return if (contentPosition in 0 until contentItems.size) {
contentPosition
} else {
null
}
}
/**
* Resolves adapter position into section type and section position.<br><br>
* adapter 위치를 섹션 타입과 섹션 위치로 해석합니다.<br>
*
* Precondition: [adapterPosition] must be in `0 until getTotalSize()`.<br>
* Callers are responsible for validating bounds before calling this function.<br><br>
* 전제 조건: [adapterPosition]은 `0 until getTotalSize()` 범위여야 합니다.<br>
* 호출자가 이 함수를 호출하기 전에 범위를 검증해야 합니다.<br>
*/
internal fun resolveSectionPosition(adapterPosition: Int): HeaderFooterRcvAdapterSectionPosition {
require(adapterPosition >= 0 && adapterPosition < getTotalSize()) {
"adapterPosition $adapterPosition is out of bounds [0, ${getTotalSize()})"
}
val headerSize = headerItems.size
val contentSize = contentItems.size
return when {
adapterPosition < headerSize -> {
HeaderFooterRcvAdapterSectionPosition(
sectionType = HeaderFooterRcvAdapterSectionType.HEADER,
adapterPosition = adapterPosition,
sectionPosition = adapterPosition,
)
}
adapterPosition < headerSize + contentSize -> {
HeaderFooterRcvAdapterSectionPosition(
sectionType = HeaderFooterRcvAdapterSectionType.CONTENT,
adapterPosition = adapterPosition,
sectionPosition = adapterPosition - headerSize,
)
}
else -> {
HeaderFooterRcvAdapterSectionPosition(
sectionType = HeaderFooterRcvAdapterSectionType.FOOTER,
adapterPosition = adapterPosition,
sectionPosition = adapterPosition - headerSize - contentSize,
)
}
}
}
}