feat(banner): 배너 시각 정렬을 보완한다

This commit is contained in:
2026-05-28 14:41:17 +09:00
parent ecb9f5a260
commit a35310e536
2 changed files with 78 additions and 3 deletions

View File

@@ -38,6 +38,7 @@ class BannerView @JvmOverloads constructor(
private var currentAdapterPosition: Int = 0
private var itemSpacingPx: Int = 0
private var spacingDecoration: RecyclerView.ItemDecoration? = null
private var shouldAlignCurrentPositionAfterLayout = false
private val autoScrollHandler = Handler(Looper.getMainLooper())
private val autoScrollRunnable = Runnable { moveToNextBanner() }
private var hasWindowAttachmentForAutoScroll = false
@@ -116,6 +117,7 @@ class BannerView @JvmOverloads constructor(
fun setItems(items: List<BannerItem>) {
this.items = items
currentIndex = 0
shouldAlignCurrentPositionAfterLayout = true
visibility = if (items.isEmpty()) GONE else VISIBLE
stopAutoScroll()
adapter.submitItems(items)
@@ -179,6 +181,15 @@ class BannerView @JvmOverloads constructor(
spacingDecoration?.let(::removeItemDecoration)
spacingDecoration = BannerSpacingDecoration(itemSpacingPx).also(::addItemDecoration)
}
counterContainer?.let { counter ->
val params = counter.layoutParams as? LayoutParams ?: return@let
params.marginEnd = (size.sideInsetDp + COUNTER_ITEM_MARGIN_DP).dpToPx()
counter.layoutParams = params
}
if (shouldAlignCurrentPositionAfterLayout) {
scrollToCurrentBanner()
shouldAlignCurrentPositionAfterLayout = false
}
}
private fun scrollToCurrentBanner() {
@@ -188,7 +199,15 @@ class BannerView @JvmOverloads constructor(
} else {
currentIndex
}
recyclerView.scrollToPosition(currentAdapterPosition)
val layoutManager = recyclerView.layoutManager as? LinearLayoutManager
if (items.size > 1 && layoutManager != null) {
layoutManager.scrollToPositionWithOffset(
currentAdapterPosition,
-(itemSpacingPx / 2)
)
} else {
recyclerView.scrollToPosition(currentAdapterPosition)
}
}
private fun moveToNextBanner() {
@@ -263,6 +282,7 @@ class BannerView @JvmOverloads constructor(
companion object {
private const val AUTO_SCROLL_INTERVAL_MS = 5_000L
private const val SCROLL_ANIMATION_DURATION_MS = 350
private const val COUNTER_ITEM_MARGIN_DP = 14
fun scrollAnimationDurationMsForTest(): Int = SCROLL_ANIMATION_DURATION_MS
}
@@ -280,7 +300,9 @@ class BannerView @JvmOverloads constructor(
parent: RecyclerView,
state: RecyclerView.State
) {
outRect.right = spacingPx
val leftSpacing = spacingPx / 2
outRect.left = leftSpacing
outRect.right = spacingPx - leftSpacing
}
}
}