fix(creator-ranking): 카드 UI 크기를 반응형 적용한다

This commit is contained in:
2026-07-10 10:16:18 +09:00
parent f477b563a2
commit 991d70f22b
4 changed files with 38 additions and 27 deletions

View File

@@ -14,6 +14,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.v2.widget.ranking.RankingResponsiveScale
import kotlin.math.max
import kotlin.math.roundToInt
@@ -61,16 +62,17 @@ class CreatorRankingLowerRowView @JvmOverloads constructor(
fun bind(item: CreatorRankingItem) {
currentItem = item
val style = CreatorRankingTextStyle.fromRank(item.rank)
val scale = RankingResponsiveScale.fromResources(resources)
val style = CreatorRankingTextStyle.fromRank(item.rank).scaledBy(scale)
requireNotNull(rankText).apply {
text = item.rank.toString()
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.rankTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.rankTextSizeSp)
applyCreatorRankingRankGradient()
}
bindDelta(item, style)
requireNotNull(nameText).apply {
text = item.displayName(context.getString(R.string.creator_ranking_inaccessible_info))
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.nameTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.nameTextSizeSp)
}
applyAccessState(item)
}
@@ -84,32 +86,36 @@ class CreatorRankingLowerRowView @JvmOverloads constructor(
private fun bindDelta(
item: CreatorRankingItem,
style: CreatorRankingTextStyle
style: CreatorRankingScaledTextStyle
) {
requireNotNull(deltaGroup).visibility = if (item.showRankChange) VISIBLE else GONE
if (!item.showRankChange) return
val presentation = CreatorRankingDeltaPresentation.from(item.rankChangeType, item.rankChangeAmount)
applyDeltaContainer(presentation)
val scale = RankingResponsiveScale.fromResources(resources)
applyDeltaContainer(presentation, scale)
requireNotNull(deltaIcon).apply {
setImageResource(presentation.iconRes)
layoutParams = (layoutParams as ViewGroup.MarginLayoutParams).apply {
width = presentation.iconWidthDp.dpToPx()
height = presentation.iconHeightDp.dpToPx()
marginStart = presentation.iconMarginStartDp.dpToPx()
width = presentation.iconWidthDp.dpToPx(scale)
height = presentation.iconHeightDp.dpToPx(scale)
marginStart = presentation.iconMarginStartDp.dpToPx(scale)
}
}
requireNotNull(deltaAmountText).apply {
text = presentation.amountText.orEmpty()
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.deltaTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.deltaTextSizeSp)
visibility = if (presentation.showAmount) VISIBLE else GONE
}
}
private fun applyDeltaContainer(presentation: CreatorRankingDeltaPresentation) {
private fun applyDeltaContainer(
presentation: CreatorRankingDeltaPresentation,
scale: Float
) {
requireNotNull(deltaGroup).apply {
setBackgroundResource(if (presentation.showPillBackground) R.drawable.bg_creator_ranking_delta else 0)
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx() else 0
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx(scale) else 0
setPadding(horizontalPadding, paddingTop, horizontalPadding, paddingBottom)
}
}
@@ -134,7 +140,7 @@ class CreatorRankingLowerRowView @JvmOverloads constructor(
}
}
private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).roundToInt()
private fun Int.dpToPx(scale: Float = 1f): Int = (this * scale * resources.displayMetrics.density).roundToInt()
private companion object {
const val FIGMA_HEIGHT_RATIO_NUMERATOR = 100

View File

@@ -8,12 +8,12 @@ import android.os.Build
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.ViewOutlineProvider
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.v2.widget.ranking.RankingResponsiveScale
import kotlin.math.roundToInt
class CreatorRankingTopCardView @JvmOverloads constructor(
@@ -57,17 +57,18 @@ class CreatorRankingTopCardView @JvmOverloads constructor(
fun bind(item: CreatorRankingItem) {
currentItem = item
val style = CreatorRankingTextStyle.fromRank(item.rank)
val scale = RankingResponsiveScale.fromResources(resources)
val style = CreatorRankingTextStyle.fromRank(item.rank).scaledBy(scale)
applyMargins(CreatorRankingTopCardMargin.fromRank(item.rank))
requireNotNull(rankText).apply {
text = item.rank.toString()
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.rankTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.rankTextSizeSp)
applyCreatorRankingRankGradient()
}
bindDelta(item, style)
requireNotNull(nameText).apply {
text = item.displayName(context.getString(R.string.creator_ranking_inaccessible_info))
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.nameTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.nameTextSizeSp)
visibility = if (text.isNullOrBlank()) INVISIBLE else VISIBLE
}
dimGradient?.visibility = VISIBLE
@@ -96,32 +97,36 @@ class CreatorRankingTopCardView @JvmOverloads constructor(
private fun bindDelta(
item: CreatorRankingItem,
style: CreatorRankingTextStyle
style: CreatorRankingScaledTextStyle
) {
requireNotNull(deltaGroup).visibility = if (item.showRankChange) VISIBLE else GONE
if (!item.showRankChange) return
val presentation = CreatorRankingDeltaPresentation.from(item.rankChangeType, item.rankChangeAmount)
applyDeltaContainer(presentation)
val scale = RankingResponsiveScale.fromResources(resources)
applyDeltaContainer(presentation, scale)
requireNotNull(deltaIcon).apply {
setImageResource(presentation.iconRes)
layoutParams = (layoutParams as MarginLayoutParams).apply {
width = presentation.iconWidthDp.dpToPx()
height = presentation.iconHeightDp.dpToPx()
marginStart = presentation.iconMarginStartDp.dpToPx()
width = presentation.iconWidthDp.dpToPx(scale)
height = presentation.iconHeightDp.dpToPx(scale)
marginStart = presentation.iconMarginStartDp.dpToPx(scale)
}
}
requireNotNull(deltaAmountText).apply {
text = presentation.amountText.orEmpty()
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.deltaTextSizeSp.toFloat())
setTextSize(TypedValue.COMPLEX_UNIT_SP, style.deltaTextSizeSp)
visibility = if (presentation.showAmount) VISIBLE else GONE
}
}
private fun applyDeltaContainer(presentation: CreatorRankingDeltaPresentation) {
private fun applyDeltaContainer(
presentation: CreatorRankingDeltaPresentation,
scale: Float
) {
requireNotNull(deltaGroup).apply {
setBackgroundResource(if (presentation.showPillBackground) R.drawable.bg_creator_ranking_delta else 0)
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx() else 0
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx(scale) else 0
setPadding(horizontalPadding, paddingTop, horizontalPadding, paddingBottom)
}
}
@@ -146,5 +151,5 @@ class CreatorRankingTopCardView @JvmOverloads constructor(
}
}
private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).roundToInt()
private fun Int.dpToPx(scale: Float = 1f): Int = (this * scale * resources.displayMetrics.density).roundToInt()
}

View File

@@ -21,7 +21,7 @@
android:id="@+id/tv_creator_ranking_rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/phosphate_solid"
android:fontFamily="@font/pattaya_regular"
android:gravity="center"
android:shadowColor="#7A000000"
android:shadowRadius="4"

View File

@@ -41,7 +41,7 @@
android:id="@+id/tv_creator_ranking_rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/phosphate_solid"
android:fontFamily="@font/pattaya_regular"
android:gravity="center"
android:padding="0dp"
android:shadowColor="#7A000000"