feat(banner): 배너 preview 회귀 테스트를 추가한다
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -16,6 +16,7 @@ class BannerAdapter(
|
||||
|
||||
private val items = mutableListOf<BannerItem>()
|
||||
private var itemSizePx: Int = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
private var previewImageResId: Int = 0
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_banner, parent, false)
|
||||
@@ -32,14 +33,24 @@ class BannerAdapter(
|
||||
}
|
||||
|
||||
fun submitItems(items: List<BannerItem>) {
|
||||
val previousItemCount = itemCount
|
||||
this.items.clear()
|
||||
this.items.addAll(items)
|
||||
notifyDataSetChanged()
|
||||
val newItemCount = itemCount
|
||||
when {
|
||||
previousItemCount == 0 && newItemCount > 0 -> notifyItemRangeInserted(0, newItemCount)
|
||||
previousItemCount > 0 && newItemCount == 0 -> notifyItemRangeRemoved(0, previousItemCount)
|
||||
previousItemCount == newItemCount -> notifyItemRangeChanged(0, newItemCount)
|
||||
else -> {
|
||||
notifyItemRangeRemoved(0, previousItemCount)
|
||||
notifyItemRangeInserted(0, newItemCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setItemSizePx(itemSizePx: Int) {
|
||||
this.itemSizePx = itemSizePx
|
||||
notifyDataSetChanged()
|
||||
notifyItemsChanged()
|
||||
}
|
||||
|
||||
fun setOnClickItem(listener: ((BannerItem) -> Unit)?) {
|
||||
@@ -50,6 +61,11 @@ class BannerAdapter(
|
||||
onBindImage = listener
|
||||
}
|
||||
|
||||
fun setPreviewImageResource(resId: Int) {
|
||||
previewImageResId = resId
|
||||
notifyItemsChanged()
|
||||
}
|
||||
|
||||
fun toRealIndex(position: Int): Int = if (items.isEmpty()) 0 else position % items.size
|
||||
|
||||
fun startPosition(realIndex: Int): Int {
|
||||
@@ -74,6 +90,7 @@ class BannerAdapter(
|
||||
height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
}
|
||||
setRadiusClipping(imageView)
|
||||
if (previewImageResId != 0) imageView.setImageResource(previewImageResId)
|
||||
onBindImage?.invoke(imageView, item)
|
||||
itemView.setOnClickListener { onClickItem?.invoke(item) }
|
||||
}
|
||||
@@ -88,6 +105,11 @@ class BannerAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyItemsChanged() {
|
||||
val count = itemCount
|
||||
if (count > 0) notifyItemRangeChanged(0, count)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val VIRTUAL_ITEM_COUNT = Int.MAX_VALUE
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ class BannerView @JvmOverloads constructor(
|
||||
separatorText = findViewById(R.id.tv_banner_counter_separator)
|
||||
totalCountText = findViewById(R.id.tv_banner_total_count)
|
||||
setUpRecyclerView()
|
||||
applyPreviewAttributes(attrs)
|
||||
updateCounter()
|
||||
}
|
||||
|
||||
@@ -114,6 +115,29 @@ class BannerView @JvmOverloads constructor(
|
||||
adapter.setOnBindImage(listener)
|
||||
}
|
||||
|
||||
private fun applyPreviewAttributes(attrs: AttributeSet?) {
|
||||
if (attrs == null) return
|
||||
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerView)
|
||||
try {
|
||||
val previewItemCount = typedArray.getInt(R.styleable.BannerView_bannerPreviewItemCount, 0)
|
||||
val previewCurrentIndex = typedArray.getInt(R.styleable.BannerView_bannerPreviewCurrentIndex, 0)
|
||||
val previewImageResId = typedArray.getResourceId(R.styleable.BannerView_bannerPreviewImage, 0)
|
||||
if (previewImageResId != 0) adapter.setPreviewImageResource(previewImageResId)
|
||||
if (previewItemCount > 0) {
|
||||
items = List(previewItemCount) { index ->
|
||||
BannerItem(bannerId = "preview-$index", imageUrl = "")
|
||||
}
|
||||
currentIndex = BannerState.from(previewItemCount, previewCurrentIndex).currentIndex
|
||||
visibility = VISIBLE
|
||||
adapter.submitItems(items)
|
||||
scrollToCurrentBanner()
|
||||
}
|
||||
} finally {
|
||||
typedArray.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpRecyclerView() {
|
||||
requireNotNull(recyclerView).apply {
|
||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
|
||||
Reference in New Issue
Block a user