refactor(creator-ranking): 어댑터 뷰 타입을 정리한다
This commit is contained in:
@@ -185,6 +185,9 @@ class HomeMainFragment : BaseFragment<FragmentV2MainHomeBinding>(
|
||||
private fun setUpCreatorRankingAdapter() {
|
||||
binding.rvHomeCreatorRankings.apply {
|
||||
layoutManager = CreatorRankingAdapter.createGridLayoutManager(requireContext())
|
||||
if (itemDecorationCount == 0) {
|
||||
addItemDecoration(CreatorRankingAdapter.createItemDecoration(requireContext()))
|
||||
}
|
||||
adapter = creatorRankingAdapter
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
@@ -16,26 +18,22 @@ class CreatorRankingAdapter(
|
||||
|
||||
private val items = mutableListOf<CreatorRankingItem>()
|
||||
|
||||
override fun getItemViewType(position: Int): Int = when (CreatorRankingPlacement.fromRank(items[position].rank).variant) {
|
||||
CreatorRankingCardVariant.Large -> VIEW_TYPE_LARGE
|
||||
CreatorRankingCardVariant.Compact -> VIEW_TYPE_COMPACT
|
||||
CreatorRankingCardVariant.Horizontal -> VIEW_TYPE_HORIZONTAL
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
val placement = CreatorRankingPlacement.fromRank(items[position].rank)
|
||||
return when (placement.viewType) {
|
||||
CreatorRankingViewType.TopTen -> VIEW_TYPE_TOP_TEN
|
||||
CreatorRankingViewType.Lower -> VIEW_TYPE_LOWER
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
VIEW_TYPE_LARGE -> LargeViewHolder(
|
||||
inflater.inflate(R.layout.view_creator_ranking_large_card, parent, false) as CreatorRankingLargeCardView,
|
||||
parent
|
||||
VIEW_TYPE_TOP_TEN -> TopTenViewHolder(
|
||||
inflater.inflate(R.layout.view_creator_ranking_top_card, parent, false) as CreatorRankingTopCardView
|
||||
)
|
||||
VIEW_TYPE_COMPACT -> CompactViewHolder(
|
||||
inflater.inflate(R.layout.view_creator_ranking_compact_card, parent, false) as CreatorRankingCompactCardView,
|
||||
parent
|
||||
)
|
||||
VIEW_TYPE_HORIZONTAL -> HorizontalViewHolder(
|
||||
inflater.inflate(R.layout.view_creator_ranking_horizontal_card, parent, false) as CreatorRankingHorizontalCardView,
|
||||
parent
|
||||
VIEW_TYPE_LOWER -> LowerViewHolder(
|
||||
inflater.inflate(R.layout.view_creator_ranking_lower_row, parent, false) as CreatorRankingLowerRowView
|
||||
)
|
||||
else -> error("Unknown viewType: $viewType")
|
||||
}
|
||||
@@ -44,9 +42,8 @@ class CreatorRankingAdapter(
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
when (holder) {
|
||||
is LargeViewHolder -> holder.bind(item)
|
||||
is CompactViewHolder -> holder.bind(item)
|
||||
is HorizontalViewHolder -> holder.bind(item)
|
||||
is TopTenViewHolder -> holder.bind(item)
|
||||
is LowerViewHolder -> holder.bind(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,66 +55,37 @@ class CreatorRankingAdapter(
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private inner class LargeViewHolder(
|
||||
private val view: CreatorRankingLargeCardView,
|
||||
private val parent: ViewGroup
|
||||
private inner class TopTenViewHolder(
|
||||
private val view: CreatorRankingTopCardView
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
bindCommon(view, item, parent)
|
||||
bindCommon(view, item)
|
||||
view.bind(item)
|
||||
view.setOnCreatorClick(onClickItem)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class CompactViewHolder(
|
||||
private val view: CreatorRankingCompactCardView,
|
||||
private val parent: ViewGroup
|
||||
private inner class LowerViewHolder(
|
||||
private val view: CreatorRankingLowerRowView
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
bindCommon(view, item, parent)
|
||||
view.bind(item)
|
||||
view.setOnCreatorClick(onClickItem)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class HorizontalViewHolder(
|
||||
private val view: CreatorRankingHorizontalCardView,
|
||||
private val parent: ViewGroup
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
bindCommon(view, item, parent)
|
||||
bindCommon(view, item)
|
||||
view.bind(item)
|
||||
view.setOnCreatorClick(onClickItem)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindCommon(
|
||||
view: CreatorRankingLargeCardView,
|
||||
item: CreatorRankingItem,
|
||||
parent: ViewGroup
|
||||
view: CreatorRankingTopCardView,
|
||||
item: CreatorRankingItem
|
||||
) {
|
||||
val size = calculateSize(item, parent)
|
||||
view.setCardSize(size)
|
||||
view.imageView().loadCreatorImage(item)
|
||||
}
|
||||
|
||||
private fun bindCommon(
|
||||
view: CreatorRankingCompactCardView,
|
||||
item: CreatorRankingItem,
|
||||
parent: ViewGroup
|
||||
view: CreatorRankingLowerRowView,
|
||||
item: CreatorRankingItem
|
||||
) {
|
||||
val size = calculateSize(item, parent)
|
||||
view.setCardSize(size)
|
||||
view.imageView().loadCreatorImage(item)
|
||||
}
|
||||
|
||||
private fun bindCommon(
|
||||
view: CreatorRankingHorizontalCardView,
|
||||
item: CreatorRankingItem,
|
||||
parent: ViewGroup
|
||||
) {
|
||||
val size = calculateSize(item, parent)
|
||||
view.setCardSize(size)
|
||||
view.imageView().loadCreatorImage(item)
|
||||
}
|
||||
|
||||
@@ -130,21 +98,6 @@ class CreatorRankingAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateSize(
|
||||
item: CreatorRankingItem,
|
||||
parent: ViewGroup
|
||||
): CreatorRankingCardSize {
|
||||
val parentWidth = parent.width.takeIf { it > 0 } ?: parent.resources.displayMetrics.widthPixels
|
||||
return CreatorRankingLayoutCalculator.calculate(
|
||||
parentWidthPx = parentWidth,
|
||||
parentHorizontalPaddingPx = parent.paddingLeft + parent.paddingRight,
|
||||
horizontalGapPx = HORIZONTAL_GAP_DP.dpToPx(parent),
|
||||
placement = CreatorRankingPlacement.fromRank(item.rank)
|
||||
)
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(parent: ViewGroup): Int = (this * parent.resources.displayMetrics.density).roundToInt()
|
||||
|
||||
companion object {
|
||||
const val GRID_SPAN_COUNT = 6
|
||||
|
||||
@@ -152,6 +105,10 @@ class CreatorRankingAdapter(
|
||||
spanSizeLookup = createSpanSizeLookup()
|
||||
}
|
||||
|
||||
fun createItemDecoration(context: Context): RecyclerView.ItemDecoration {
|
||||
return CreatorRankingItemDecoration(HORIZONTAL_GAP_DP.dpToPx(context))
|
||||
}
|
||||
|
||||
fun createSpanSizeLookup(): GridLayoutManager.SpanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||
override fun getSpanSize(position: Int): Int = when (CreatorRankingPlacement.fromRank(position + 1).itemsPerRow) {
|
||||
1 -> GRID_SPAN_COUNT
|
||||
@@ -161,9 +118,50 @@ class CreatorRankingAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
private const val VIEW_TYPE_LARGE = 1
|
||||
private const val VIEW_TYPE_COMPACT = 2
|
||||
private const val VIEW_TYPE_HORIZONTAL = 3
|
||||
private const val HORIZONTAL_GAP_DP = 4
|
||||
private const val VIEW_TYPE_TOP_TEN = 1
|
||||
private const val VIEW_TYPE_LOWER = 2
|
||||
private const val HORIZONTAL_GAP_DP = 8
|
||||
|
||||
private fun Int.dpToPx(context: Context): Int = (this * context.resources.displayMetrics.density).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
internal class CreatorRankingItemDecoration(
|
||||
private val spacingPx: Int
|
||||
) : RecyclerView.ItemDecoration() {
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
val itemCount = parent.adapter?.itemCount ?: return
|
||||
if (position == RecyclerView.NO_POSITION) return
|
||||
|
||||
outRect.set(offsetsForPosition(position, itemCount))
|
||||
}
|
||||
|
||||
fun offsetsForPosition(
|
||||
adapterPosition: Int,
|
||||
itemCount: Int
|
||||
): Rect {
|
||||
val placement = CreatorRankingPlacement.fromRank(adapterPosition + 1)
|
||||
val indexInRow = adapterPosition.indexInRankingRow(placement.itemsPerRow)
|
||||
return Rect().apply {
|
||||
left = indexInRow * spacingPx / placement.itemsPerRow
|
||||
right = spacingPx - (indexInRow + 1) * spacingPx / placement.itemsPerRow
|
||||
if (adapterPosition < itemCount - 1) bottom = spacingPx
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.indexInRankingRow(itemsPerRow: Int): Int {
|
||||
return when (this) {
|
||||
0 -> 0
|
||||
in 1..6 -> (this - 1) % itemsPerRow
|
||||
in 7..9 -> (this - 7) % itemsPerRow
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,5 +360,5 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_tab_bar_home"
|
||||
tools:listitem="@layout/view_creator_ranking_horizontal_card" />
|
||||
tools:listitem="@layout/view_creator_ranking_lower_row" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
Reference in New Issue
Block a user