fix(content): 전체 탭 grid 폭을 주입한다

This commit is contained in:
2026-06-25 18:31:39 +09:00
parent 78e0a53018
commit 136fdced17
5 changed files with 99 additions and 9 deletions

View File

@@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.doOnLayout
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -45,6 +46,7 @@ import kr.co.vividnext.sodalive.v2.main.content.model.toContentBannerIntent
import kr.co.vividnext.sodalive.v2.main.content.model.toContentBannerRoute
import kr.co.vividnext.sodalive.v2.main.content.model.usesDayOfWeekQuery
import kr.co.vividnext.sodalive.v2.main.content.model.usesSeriesItems
import kr.co.vividnext.sodalive.v2.main.content.ui.CONTENT_ALL_GRID_SPAN_COUNT
import kr.co.vividnext.sodalive.v2.main.content.ui.CONTENT_RECOMMENDED_GRID_SPAN_COUNT
import kr.co.vividnext.sodalive.v2.main.content.ui.ContentAllAudioCardAdapter
import kr.co.vividnext.sodalive.v2.main.content.ui.ContentAllSeriesCardAdapter
@@ -55,6 +57,7 @@ import kr.co.vividnext.sodalive.v2.main.content.ui.ContentNewAndHotAdapter
import kr.co.vividnext.sodalive.v2.main.content.ui.ContentOriginalSeriesAdapter
import kr.co.vividnext.sodalive.v2.main.content.ui.addContentGridItemSpacing
import kr.co.vividnext.sodalive.v2.main.content.ui.addContentHorizontalItemSpacing
import kr.co.vividnext.sodalive.v2.main.content.ui.calculateContentGridItemWidthPx
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardSize
import kr.co.vividnext.sodalive.v2.widget.contentranking.ContentRankingAdapter
import kr.co.vividnext.sodalive.v2.widget.contentranking.ContentRankingItem
@@ -281,6 +284,7 @@ class ContentMainFragment : BaseFragment<FragmentV2MainContentBinding>(
layoutManager = contentAllGridLayoutManager
adapter = contentAllAudioCardAdapter
addContentGridItemSpacing(CONTENT_ALL_GRID_SPAN_COUNT)
doOnLayout { updateAllTabGridItemWidth() }
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
@@ -357,6 +361,7 @@ class ContentMainFragment : BaseFragment<FragmentV2MainContentBinding>(
bindAllTabControls(state)
binding.layoutContentAllSurface.visibility = View.VISIBLE
hideAllTabEmptyError()
updateAllTabGridItemWidth()
if (state.selectedType.usesSeriesItems()) {
binding.rvContentAllItems.adapter = contentAllSeriesCardAdapter
contentAllAudioCardAdapter.submitItems(emptyList())
@@ -372,6 +377,12 @@ class ContentMainFragment : BaseFragment<FragmentV2MainContentBinding>(
}
}
private fun updateAllTabGridItemWidth() {
val widthPx = binding.rvContentAllItems.calculateContentGridItemWidthPx(CONTENT_ALL_GRID_SPAN_COUNT)
contentAllAudioCardAdapter.setGridItemWidthPx(widthPx)
contentAllSeriesCardAdapter.setGridItemWidthPx(widthPx)
}
private fun bindAllTabEmpty(state: MainContentAllTabUiState.Empty) {
bindAllTabControls(state)
binding.layoutContentAllSurface.visibility = View.VISIBLE
@@ -589,6 +600,5 @@ class ContentMainFragment : BaseFragment<FragmentV2MainContentBinding>(
private const val CONTENT_TAB_RECOMMENDATION = 0
private const val CONTENT_TAB_RANKING = 1
private const val CONTENT_TAB_ALL = 2
private const val CONTENT_ALL_GRID_SPAN_COUNT = 3
}
}

View File

@@ -6,13 +6,19 @@ import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.databinding.ItemContentAudioCardBinding
import kr.co.vividnext.sodalive.extensions.loadUrl
import kr.co.vividnext.sodalive.v2.main.content.model.MainContentAllAudioUiModel
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardSize
class ContentAllAudioCardAdapter(
private val onAudioClick: (Long) -> Unit = {}
) : RecyclerView.Adapter<ContentAllAudioCardAdapter.ViewHolder>() {
private var items: List<MainContentAllAudioUiModel> = emptyList()
private var gridItemWidthPx: Int = 0
fun setGridItemWidthPx(widthPx: Int) {
if (widthPx <= 0 || gridItemWidthPx == widthPx) return
gridItemWidthPx = widthPx
notifyDataSetChanged()
}
fun submitItems(items: List<MainContentAllAudioUiModel>) {
this.items = items
@@ -27,7 +33,10 @@ class ContentAllAudioCardAdapter(
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
holder.bind(
item = items[position],
gridItemWidthPx = gridItemWidthPx
)
}
override fun getItemCount(): Int = items.size
@@ -36,8 +45,8 @@ class ContentAllAudioCardAdapter(
private val binding: ItemContentAudioCardBinding,
private val onAudioClick: (Long) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: MainContentAllAudioUiModel) = with(binding.audioContentCard.root) {
setSize(AudioContentCardSize.Small)
fun bind(item: MainContentAllAudioUiModel, gridItemWidthPx: Int) = with(binding.audioContentCard.root) {
setGridItemWidthPx(gridItemWidthPx)
setContent(item.title, item.creatorNickname)
setTags(item.tags)
setAdultVisible(item.showAdultBadge)

View File

@@ -6,13 +6,19 @@ import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.databinding.ItemContentAllSeriesCardBinding
import kr.co.vividnext.sodalive.extensions.loadUrl
import kr.co.vividnext.sodalive.v2.main.content.model.MainContentAllSeriesUiModel
import kr.co.vividnext.sodalive.v2.widget.SeriesContentCardSize
class ContentAllSeriesCardAdapter(
private val onSeriesClick: (Long) -> Unit = {}
) : RecyclerView.Adapter<ContentAllSeriesCardAdapter.ViewHolder>() {
private var items: List<MainContentAllSeriesUiModel> = emptyList()
private var gridItemWidthPx: Int = 0
fun setGridItemWidthPx(widthPx: Int) {
if (widthPx <= 0 || gridItemWidthPx == widthPx) return
gridItemWidthPx = widthPx
notifyDataSetChanged()
}
fun submitItems(items: List<MainContentAllSeriesUiModel>) {
this.items = items
@@ -27,7 +33,10 @@ class ContentAllSeriesCardAdapter(
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
holder.bind(
item = items[position],
gridItemWidthPx = gridItemWidthPx
)
}
override fun getItemCount(): Int = items.size
@@ -36,8 +45,8 @@ class ContentAllSeriesCardAdapter(
private val binding: ItemContentAllSeriesCardBinding,
private val onSeriesClick: (Long) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: MainContentAllSeriesUiModel) = with(binding.seriesContentCard.root) {
setSize(SeriesContentCardSize.Small)
fun bind(item: MainContentAllSeriesUiModel, gridItemWidthPx: Int) = with(binding.seriesContentCard.root) {
setGridItemWidthPx(gridItemWidthPx)
setContent(item.title, item.creatorNickname)
setOriginalVisible(item.showOriginalTag)
setAdultVisible(item.showAdultBadge)

View File

@@ -14,6 +14,13 @@ fun RecyclerView.addContentGridItemSpacing(spanCount: Int = CONTENT_RECOMMENDED_
if (itemDecorationCount == 0) addItemDecoration(ContentGridItemDecoration(spanCount))
}
fun RecyclerView.calculateContentGridItemWidthPx(spanCount: Int): Int {
val availableWidth = measuredWidth - paddingLeft - paddingRight
if (availableWidth <= 0 || spanCount <= 0) return 0
val totalGap = GRID_ITEM_GAP_DP.dpToPx() * (spanCount - 1)
return ((availableWidth - totalGap) / spanCount).roundToInt()
}
private class ContentHorizontalItemDecoration : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val position = parent.getChildAdapterPosition(view)
@@ -41,3 +48,4 @@ private const val HORIZONTAL_ITEM_GAP_DP = 8
private const val GRID_ITEM_GAP_DP = 8
private const val GRID_ITEM_VERTICAL_GAP_DP = 28
const val CONTENT_RECOMMENDED_GRID_SPAN_COUNT = 2
const val CONTENT_ALL_GRID_SPAN_COUNT = 3