chore(creator-ranking): 기존 카드 뷰를 제거한다
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
enum class CreatorRankingCardVariant {
|
||||
Large,
|
||||
Compact,
|
||||
Horizontal
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Outline
|
||||
import android.graphics.RenderEffect
|
||||
import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CreatorRankingCompactCardView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var image: ImageView? = null
|
||||
private var dimGradient: View? = null
|
||||
private var deltaGroup: View? = null
|
||||
private var rankText: TextView? = null
|
||||
private var deltaAmountText: TextView? = null
|
||||
private var deltaIcon: ImageView? = null
|
||||
private var nameText: TextView? = null
|
||||
private var currentItem: CreatorRankingItem? = null
|
||||
private var clickListener: ((CreatorRankingItem) -> Unit)? = null
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
image = findViewById(R.id.iv_creator_ranking_image)
|
||||
dimGradient = findViewById(R.id.v_creator_ranking_dim_gradient)
|
||||
deltaGroup = findViewById(R.id.ll_creator_ranking_delta)
|
||||
rankText = findViewById(R.id.tv_creator_ranking_rank)
|
||||
deltaAmountText = findViewById(R.id.tv_creator_ranking_delta_amount)
|
||||
deltaIcon = findViewById(R.id.iv_creator_ranking_delta_icon)
|
||||
nameText = findViewById(R.id.tv_creator_ranking_name)
|
||||
clipToOutline = true
|
||||
outlineProvider = roundOutlineProvider()
|
||||
imageView().outlineProvider = roundOutlineProvider()
|
||||
imageView().clipToOutline = true
|
||||
}
|
||||
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
currentItem = item
|
||||
requireNotNull(rankText).apply {
|
||||
text = item.rank.toString()
|
||||
applyCreatorRankingRankGradient()
|
||||
}
|
||||
bindDelta(item)
|
||||
requireNotNull(nameText).apply {
|
||||
text = item.displayName(context.getString(R.string.creator_ranking_inaccessible_info))
|
||||
visibility = if (text.isNullOrBlank()) View.INVISIBLE else View.VISIBLE
|
||||
}
|
||||
dimGradient?.visibility = View.VISIBLE
|
||||
applyAccessState(item)
|
||||
}
|
||||
|
||||
fun setCardSize(size: CreatorRankingCardSize) {
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(size.widthPx, size.heightPx)).apply {
|
||||
width = size.widthPx
|
||||
height = size.heightPx
|
||||
}
|
||||
positionViews(size)
|
||||
}
|
||||
|
||||
fun imageView(): ImageView = requireNotNull(image)
|
||||
|
||||
fun setOnCreatorClick(listener: ((CreatorRankingItem) -> Unit)?) {
|
||||
clickListener = listener
|
||||
currentItem?.let(::applyAccessState)
|
||||
}
|
||||
|
||||
private fun bindDelta(item: CreatorRankingItem) {
|
||||
requireNotNull(deltaGroup).visibility = if (item.showRankChange) View.VISIBLE else View.GONE
|
||||
if (!item.showRankChange) return
|
||||
|
||||
val presentation = CreatorRankingDeltaPresentation.from(item.rankChangeType, item.rankChangeAmount)
|
||||
applyDeltaContainer(presentation)
|
||||
requireNotNull(deltaIcon).apply {
|
||||
setImageResource(presentation.iconRes)
|
||||
layoutParams = (layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
width = presentation.iconWidthDp.dpToPx()
|
||||
height = presentation.iconHeightDp.dpToPx()
|
||||
marginStart = presentation.iconMarginStartDp.dpToPx()
|
||||
}
|
||||
}
|
||||
requireNotNull(deltaAmountText).apply {
|
||||
text = presentation.amountText.orEmpty()
|
||||
visibility = if (presentation.showAmount) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyDeltaContainer(presentation: CreatorRankingDeltaPresentation) {
|
||||
requireNotNull(deltaGroup).apply {
|
||||
setBackgroundResource(if (presentation.showPillBackground) R.drawable.bg_creator_ranking_delta else 0)
|
||||
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx() else 0
|
||||
setPadding(horizontalPadding, paddingTop, horizontalPadding, paddingBottom)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyAccessState(item: CreatorRankingItem) {
|
||||
applyBlur(item.isInaccessible)
|
||||
isClickable = item.isTouchable && clickListener != null
|
||||
setOnClickListener(if (isClickable) View.OnClickListener { clickListener?.invoke(item) } else null)
|
||||
}
|
||||
|
||||
private fun positionViews(size: CreatorRankingCardSize) {
|
||||
if (size.widthPx <= SMALL_THRESHOLD_PX) {
|
||||
requireNotNull(rankText).textSize = 40f
|
||||
requireNotNull(nameText).textSize = 14f
|
||||
positionSmall(size)
|
||||
} else {
|
||||
requireNotNull(rankText).textSize = 54f
|
||||
requireNotNull(nameText).textSize = 22f
|
||||
positionMedium(size)
|
||||
}
|
||||
requireNotNull(rankText).applyCreatorRankingRankGradient()
|
||||
}
|
||||
|
||||
private fun positionMedium(size: CreatorRankingCardSize) {
|
||||
val scale = size.widthPx / 185f
|
||||
requireNotNull(rankText).layoutParams = LayoutParams((56 * scale).roundToInt(), (70 * scale).roundToInt())
|
||||
requireNotNull(rankText).setPadding(0, 0, 0, (6 * scale).roundToInt())
|
||||
findViewById<View>(R.id.ll_creator_ranking_delta).layoutParams = LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = (10 * scale).roundToInt()
|
||||
topMargin = (70 * scale).roundToInt()
|
||||
}
|
||||
requireNotNull(nameText).layoutParams = LayoutParams(
|
||||
(165 * scale).roundToInt(),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = ((size.widthPx - (165 * scale)) / 2f).roundToInt()
|
||||
topMargin = (145 * scale).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun positionSmall(size: CreatorRankingCardSize) {
|
||||
val scale = size.widthPx / 122f
|
||||
requireNotNull(rankText).layoutParams = LayoutParams(
|
||||
(52 * scale).roundToInt(),
|
||||
(50 * scale).roundToInt()
|
||||
).apply {
|
||||
leftMargin = 0
|
||||
}
|
||||
requireNotNull(rankText).setPadding(0, 0, 0, (5 * scale).roundToInt())
|
||||
findViewById<View>(R.id.ll_creator_ranking_delta).layoutParams = LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = (10 * scale).roundToInt()
|
||||
topMargin = (50 * scale).roundToInt()
|
||||
}
|
||||
requireNotNull(nameText).layoutParams = LayoutParams(
|
||||
(102 * scale).roundToInt(),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = ((size.widthPx - (102 * scale)) / 2f).roundToInt()
|
||||
topMargin = (98 * scale).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyBlur(enabled: Boolean) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
imageView().setRenderEffect(
|
||||
if (enabled) RenderEffect.createBlurEffect(16f, 16f, Shader.TileMode.CLAMP) else null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun roundOutlineProvider() = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(0, 0, view.width, view.height, 14.dpToPx().toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).roundToInt()
|
||||
|
||||
private companion object {
|
||||
const val SMALL_THRESHOLD_PX = 140
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Outline
|
||||
import android.graphics.RenderEffect
|
||||
import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CreatorRankingHorizontalCardView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var rankGroup: View? = null
|
||||
private var image: ImageView? = null
|
||||
private var rankText: TextView? = null
|
||||
private var deltaAmountText: TextView? = null
|
||||
private var deltaIcon: ImageView? = null
|
||||
private var nameText: TextView? = null
|
||||
private var currentItem: CreatorRankingItem? = null
|
||||
private var clickListener: ((CreatorRankingItem) -> Unit)? = null
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
rankGroup = findViewById(R.id.ll_creator_ranking_rank_group)
|
||||
image = findViewById(R.id.iv_creator_ranking_image)
|
||||
rankText = findViewById(R.id.tv_creator_ranking_rank)
|
||||
deltaAmountText = findViewById(R.id.tv_creator_ranking_delta_amount)
|
||||
deltaIcon = findViewById(R.id.iv_creator_ranking_delta_icon)
|
||||
nameText = findViewById(R.id.tv_creator_ranking_name)
|
||||
imageView().outlineProvider = roundOutlineProvider()
|
||||
imageView().clipToOutline = true
|
||||
}
|
||||
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
currentItem = item
|
||||
requireNotNull(rankText).apply {
|
||||
text = item.rank.toString()
|
||||
applyCreatorRankingRankGradient()
|
||||
}
|
||||
bindDelta(item)
|
||||
requireNotNull(nameText).text = item.displayName(context.getString(R.string.creator_ranking_inaccessible_info))
|
||||
applyAccessState(item)
|
||||
}
|
||||
|
||||
fun setCardSize(size: CreatorRankingCardSize) {
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(size.widthPx, size.heightPx)).apply {
|
||||
width = size.widthPx
|
||||
height = size.heightPx
|
||||
}
|
||||
positionViews(size)
|
||||
}
|
||||
|
||||
fun imageView(): ImageView = requireNotNull(image)
|
||||
|
||||
fun setOnCreatorClick(listener: ((CreatorRankingItem) -> Unit)?) {
|
||||
clickListener = listener
|
||||
currentItem?.let(::applyAccessState)
|
||||
}
|
||||
|
||||
private fun bindDelta(item: CreatorRankingItem) {
|
||||
val deltaGroup = findViewById<View>(R.id.ll_creator_ranking_delta)
|
||||
deltaGroup.visibility = if (item.showRankChange) View.VISIBLE else View.GONE
|
||||
if (!item.showRankChange) return
|
||||
|
||||
val presentation = CreatorRankingDeltaPresentation.from(item.rankChangeType, item.rankChangeAmount)
|
||||
applyDeltaContainer(presentation)
|
||||
requireNotNull(deltaIcon).apply {
|
||||
setImageResource(presentation.iconRes)
|
||||
layoutParams = (layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
width = presentation.iconWidthDp.dpToPx()
|
||||
height = presentation.iconHeightDp.dpToPx()
|
||||
marginStart = presentation.iconMarginStartDp.dpToPx()
|
||||
}
|
||||
}
|
||||
requireNotNull(deltaAmountText).apply {
|
||||
text = presentation.amountText.orEmpty()
|
||||
visibility = if (presentation.showAmount) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyDeltaContainer(presentation: CreatorRankingDeltaPresentation) {
|
||||
findViewById<View>(R.id.ll_creator_ranking_delta).apply {
|
||||
setBackgroundResource(if (presentation.showPillBackground) R.drawable.bg_creator_ranking_delta else 0)
|
||||
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx() else 0
|
||||
setPadding(horizontalPadding, paddingTop, horizontalPadding, paddingBottom)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyAccessState(item: CreatorRankingItem) {
|
||||
applyBlur(item.isInaccessible)
|
||||
isClickable = item.isTouchable && clickListener != null
|
||||
setOnClickListener(if (isClickable) View.OnClickListener { clickListener?.invoke(item) } else null)
|
||||
}
|
||||
|
||||
private fun positionViews(size: CreatorRankingCardSize) {
|
||||
val scale = size.widthPx / 374f
|
||||
requireNotNull(rankGroup).layoutParams = LayoutParams(
|
||||
(49 * scale).roundToInt(),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = (14 * scale).roundToInt()
|
||||
topMargin = (12 * scale).roundToInt()
|
||||
}
|
||||
requireNotNull(rankText).layoutParams = android.widget.LinearLayout.LayoutParams(
|
||||
(48 * scale).roundToInt(),
|
||||
(52 * scale).roundToInt()
|
||||
)
|
||||
requireNotNull(rankText).setPadding(0, 0, 0, (4 * scale).roundToInt())
|
||||
requireNotNull(rankText).applyCreatorRankingRankGradient()
|
||||
imageView().layoutParams = LayoutParams((80 * scale).roundToInt(), (80 * scale).roundToInt()).apply {
|
||||
leftMargin = (77 * scale).roundToInt()
|
||||
topMargin = (10 * scale).roundToInt()
|
||||
}
|
||||
requireNotNull(nameText).layoutParams = LayoutParams(
|
||||
(189 * scale).roundToInt(),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = (171 * scale).roundToInt()
|
||||
topMargin = (39 * scale).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyBlur(enabled: Boolean) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
imageView().setRenderEffect(
|
||||
if (enabled) RenderEffect.createBlurEffect(16f, 16f, Shader.TileMode.CLAMP) else null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun roundOutlineProvider() = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(0, 0, view.width, view.height, 14.dpToPx().toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).roundToInt()
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Outline
|
||||
import android.graphics.RenderEffect
|
||||
import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CreatorRankingLargeCardView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var image: ImageView? = null
|
||||
private var dimGradient: View? = null
|
||||
private var deltaGroup: View? = null
|
||||
private var rankText: TextView? = null
|
||||
private var deltaAmountText: TextView? = null
|
||||
private var deltaIcon: ImageView? = null
|
||||
private var nameText: TextView? = null
|
||||
private var currentItem: CreatorRankingItem? = null
|
||||
private var clickListener: ((CreatorRankingItem) -> Unit)? = null
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
image = findViewById(R.id.iv_creator_ranking_image)
|
||||
dimGradient = findViewById(R.id.v_creator_ranking_dim_gradient)
|
||||
deltaGroup = findViewById(R.id.ll_creator_ranking_delta)
|
||||
rankText = findViewById(R.id.tv_creator_ranking_rank)
|
||||
deltaAmountText = findViewById(R.id.tv_creator_ranking_delta_amount)
|
||||
deltaIcon = findViewById(R.id.iv_creator_ranking_delta_icon)
|
||||
nameText = findViewById(R.id.tv_creator_ranking_name)
|
||||
clipToOutline = true
|
||||
outlineProvider = roundOutlineProvider()
|
||||
imageView().outlineProvider = roundOutlineProvider()
|
||||
imageView().clipToOutline = true
|
||||
}
|
||||
|
||||
fun bind(item: CreatorRankingItem) {
|
||||
currentItem = item
|
||||
requireNotNull(rankText).apply {
|
||||
text = item.rank.toString()
|
||||
applyCreatorRankingRankGradient()
|
||||
}
|
||||
bindDelta(item)
|
||||
requireNotNull(nameText).apply {
|
||||
text = item.displayName(context.getString(R.string.creator_ranking_inaccessible_info))
|
||||
visibility = if (text.isNullOrBlank()) View.INVISIBLE else View.VISIBLE
|
||||
}
|
||||
dimGradient?.visibility = View.VISIBLE
|
||||
applyAccessState(item)
|
||||
}
|
||||
|
||||
fun setCardSize(size: CreatorRankingCardSize) {
|
||||
layoutParams = (layoutParams ?: ViewGroup.LayoutParams(size.widthPx, size.heightPx)).apply {
|
||||
width = size.widthPx
|
||||
height = size.heightPx
|
||||
}
|
||||
positionViews(size)
|
||||
}
|
||||
|
||||
fun imageView(): ImageView = requireNotNull(image)
|
||||
|
||||
fun setOnCreatorClick(listener: ((CreatorRankingItem) -> Unit)?) {
|
||||
clickListener = listener
|
||||
currentItem?.let(::applyAccessState)
|
||||
}
|
||||
|
||||
private fun bindDelta(item: CreatorRankingItem) {
|
||||
requireNotNull(deltaGroup).visibility = if (item.showRankChange) View.VISIBLE else View.GONE
|
||||
if (!item.showRankChange) return
|
||||
|
||||
val presentation = CreatorRankingDeltaPresentation.from(item.rankChangeType, item.rankChangeAmount)
|
||||
applyDeltaContainer(presentation)
|
||||
requireNotNull(deltaIcon).apply {
|
||||
setImageResource(presentation.iconRes)
|
||||
layoutParams = (layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||
width = presentation.iconWidthDp.dpToPx()
|
||||
height = presentation.iconHeightDp.dpToPx()
|
||||
marginStart = presentation.iconMarginStartDp.dpToPx()
|
||||
}
|
||||
}
|
||||
requireNotNull(deltaAmountText).apply {
|
||||
text = presentation.amountText.orEmpty()
|
||||
visibility = if (presentation.showAmount) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyDeltaContainer(presentation: CreatorRankingDeltaPresentation) {
|
||||
requireNotNull(deltaGroup).apply {
|
||||
setBackgroundResource(if (presentation.showPillBackground) R.drawable.bg_creator_ranking_delta else 0)
|
||||
val horizontalPadding = if (presentation.showPillBackground) 4.dpToPx() else 0
|
||||
setPadding(horizontalPadding, paddingTop, horizontalPadding, paddingBottom)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyAccessState(item: CreatorRankingItem) {
|
||||
applyBlur(item.isInaccessible)
|
||||
isClickable = item.isTouchable && clickListener != null
|
||||
setOnClickListener(if (isClickable) View.OnClickListener { clickListener?.invoke(item) } else null)
|
||||
}
|
||||
|
||||
private fun positionViews(size: CreatorRankingCardSize) {
|
||||
val scale = size.widthPx / FIGMA_SIZE.toFloat()
|
||||
requireNotNull(rankText).layoutParams = LayoutParams((86 * scale).roundToInt(), (116 * scale).roundToInt()).apply {
|
||||
leftMargin = 0
|
||||
topMargin = 0
|
||||
}
|
||||
requireNotNull(rankText).setPadding(0, 0, 0, (10 * scale).roundToInt())
|
||||
requireNotNull(rankText).applyCreatorRankingRankGradient()
|
||||
requireNotNull(nameText).layoutParams = LayoutParams(
|
||||
(334 * scale).roundToInt(),
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = ((size.widthPx - (334 * scale)) / 2f).roundToInt()
|
||||
topMargin = (305 * scale).roundToInt()
|
||||
}
|
||||
findViewById<View>(R.id.ll_creator_ranking_delta).layoutParams = LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
leftMargin = (20 * scale).roundToInt()
|
||||
topMargin = (116 * scale).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyBlur(enabled: Boolean) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
imageView().setRenderEffect(
|
||||
if (enabled) RenderEffect.createBlurEffect(16f, 16f, Shader.TileMode.CLAMP) else null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun roundOutlineProvider() = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(0, 0, view.width, view.height, 14.dpToPx().toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).roundToInt()
|
||||
|
||||
private companion object {
|
||||
const val FIGMA_SIZE = 374
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.creatorranking
|
||||
|
||||
object CreatorRankingLayoutCalculator {
|
||||
private const val HORIZONTAL_FIGMA_WIDTH = 374
|
||||
private const val HORIZONTAL_FIGMA_HEIGHT = 100
|
||||
|
||||
fun calculate(
|
||||
parentWidthPx: Int,
|
||||
parentHorizontalPaddingPx: Int = 0,
|
||||
horizontalGapPx: Int,
|
||||
placement: CreatorRankingPlacement
|
||||
): CreatorRankingCardSize {
|
||||
require(parentWidthPx > 0) { "parentWidthPx must be > 0." }
|
||||
require(parentHorizontalPaddingPx >= 0) { "parentHorizontalPaddingPx must be >= 0." }
|
||||
require(horizontalGapPx >= 0) { "horizontalGapPx must be >= 0." }
|
||||
require(placement.itemsPerRow > 0) { "itemsPerRow must be > 0." }
|
||||
|
||||
val totalGap = horizontalGapPx * (placement.itemsPerRow - 1)
|
||||
val availableWidth = parentWidthPx - parentHorizontalPaddingPx
|
||||
require(availableWidth > 0) { "available width must be > 0." }
|
||||
val width = (availableWidth - totalGap) / placement.itemsPerRow
|
||||
val height = when (placement.variant) {
|
||||
CreatorRankingCardVariant.Large,
|
||||
CreatorRankingCardVariant.Compact -> width
|
||||
CreatorRankingCardVariant.Horizontal -> (width * HORIZONTAL_FIGMA_HEIGHT) / HORIZONTAL_FIGMA_WIDTH
|
||||
}
|
||||
|
||||
return CreatorRankingCardSize(widthPx = width, heightPx = height)
|
||||
}
|
||||
}
|
||||
|
||||
data class CreatorRankingCardSize(
|
||||
val widthPx: Int,
|
||||
val heightPx: Int
|
||||
)
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingCompactCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_creator_ranking_image"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<View
|
||||
android:id="@+id/v_creator_ranking_dim_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_creator_ranking_dim_gradient" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_rank"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/pattaya_regular"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:shadowColor="#7A000000"
|
||||
android:shadowRadius="4"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="54sp"
|
||||
tools:text="2" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_creator_ranking_delta"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_creator_ranking_delta"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_delta_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/medium"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_delta_icon"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="2dp"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/ic_rank_caret_increase" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/bold"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="22sp"
|
||||
tools:text="크리에이터 이름" />
|
||||
</kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingCompactCardView>
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingHorizontalCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_creator_ranking_rank_group"
|
||||
android:layout_width="49dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_rank"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/pattaya_regular"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:shadowColor="#7A000000"
|
||||
android:shadowRadius="4"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="40sp"
|
||||
tools:text="11" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_creator_ranking_delta"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_creator_ranking_delta"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_delta_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/medium"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_delta_icon"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="2dp"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/ic_rank_caret_increase" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_image"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_creator_ranking_image"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/bold"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
tools:text="크리에이터 이름" />
|
||||
</kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingHorizontalCardView>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingLargeCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_creator_ranking_image"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<View
|
||||
android:id="@+id/v_creator_ranking_dim_gradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_creator_ranking_dim_gradient" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_rank"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/pattaya_regular"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:shadowColor="#7A000000"
|
||||
android:shadowRadius="4"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="96sp"
|
||||
tools:text="1" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_creator_ranking_delta"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_creator_ranking_delta"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_delta_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/medium"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_creator_ranking_delta_icon"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="2dp"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/ic_rank_caret_increase" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_creator_ranking_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="@font/bold"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp"
|
||||
tools:text="크리에이터 이름" />
|
||||
</kr.co.vividnext.sodalive.v2.widget.creatorranking.CreatorRankingLargeCardView>
|
||||
Reference in New Issue
Block a user