fix(feed): 커뮤니티 이미지 원본비율 높이를 적용한다
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.feed
|
||||
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun calculateFeedCommunityImageHeight(
|
||||
containerWidthPx: Int,
|
||||
intrinsicWidthPx: Int,
|
||||
intrinsicHeightPx: Int
|
||||
): Int? {
|
||||
if (containerWidthPx <= 0 || intrinsicWidthPx <= 0 || intrinsicHeightPx <= 0) return null
|
||||
return (containerWidthPx * intrinsicHeightPx.toFloat() / intrinsicWidthPx).roundToInt()
|
||||
}
|
||||
@@ -62,6 +62,7 @@ class FeedCommunityView @JvmOverloads constructor(
|
||||
val isLocked = item.price > 0 && !item.existOrdered
|
||||
val hasImage = !item.imageUrl.isNullOrBlank()
|
||||
requireNotNull(communityImageContainer).isVisible = hasImage || isLocked
|
||||
resetCommunityImageHeight()
|
||||
requireNotNull(communityImage).isVisible = hasImage
|
||||
if (!hasImage || isLocked) {
|
||||
requireNotNull(communityImage).setImageDrawable(null)
|
||||
@@ -79,6 +80,33 @@ class FeedCommunityView @JvmOverloads constructor(
|
||||
|
||||
fun boundItem(): FeedItem.Community? = currentItem
|
||||
|
||||
fun applyCommunityImageSize(
|
||||
intrinsicWidthPx: Int,
|
||||
intrinsicHeightPx: Int
|
||||
) {
|
||||
val container = requireNotNull(communityImageContainer)
|
||||
val width = container.width.takeIf { it > 0 }
|
||||
?: container.measuredWidth.takeIf { it > 0 }
|
||||
?: (width - paddingLeft - paddingRight).takeIf { it > 0 }
|
||||
?: run {
|
||||
post { applyCommunityImageSize(intrinsicWidthPx, intrinsicHeightPx) }
|
||||
return
|
||||
}
|
||||
val imageHeight = calculateFeedCommunityImageHeight(
|
||||
containerWidthPx = width,
|
||||
intrinsicWidthPx = intrinsicWidthPx,
|
||||
intrinsicHeightPx = intrinsicHeightPx
|
||||
) ?: return
|
||||
container.layoutParams = container.layoutParams.apply { height = imageHeight }
|
||||
}
|
||||
|
||||
private fun resetCommunityImageHeight() {
|
||||
val container = requireNotNull(communityImageContainer)
|
||||
container.layoutParams = container.layoutParams.apply {
|
||||
height = DEFAULT_IMAGE_HEIGHT_DP.dpToPx()
|
||||
}
|
||||
}
|
||||
|
||||
fun setFeedSize(size: FeedSize) {
|
||||
updateRootWidth(size.rootWidthDp.dpToPx())
|
||||
}
|
||||
@@ -128,5 +156,6 @@ class FeedCommunityView @JvmOverloads constructor(
|
||||
private companion object {
|
||||
const val CARD_RADIUS_DP = 14
|
||||
const val COMMUNITY_IMAGE_RADIUS_DP = 14
|
||||
const val DEFAULT_IMAGE_HEIGHT_DP = 236
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +67,9 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_feed_community_image_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="236dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_14"
|
||||
android:background="@drawable/bg_feed_community_image"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
@@ -76,9 +77,8 @@
|
||||
android:id="@+id/iv_feed_community_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_feed_community_image"
|
||||
android:contentDescription="@string/a11y_feed_content_image"
|
||||
android:scaleType="centerCrop"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/ic_launcher_background" />
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package kr.co.vividnext.sodalive.v2.widget.feed
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
class FeedCommunityImageSizeTest {
|
||||
|
||||
@Test
|
||||
fun `커뮤니티 이미지는 원본 비율로 높이를 계산한다`() {
|
||||
val height = calculateFeedCommunityImageHeight(
|
||||
containerWidthPx = 300,
|
||||
intrinsicWidthPx = 1200,
|
||||
intrinsicHeightPx = 800
|
||||
)
|
||||
|
||||
assertEquals(200, height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `커뮤니티 이미지는 특정 최대 높이로 제한하지 않는다`() {
|
||||
val height = calculateFeedCommunityImageHeight(
|
||||
containerWidthPx = 300,
|
||||
intrinsicWidthPx = 600,
|
||||
intrinsicHeightPx = 1800
|
||||
)
|
||||
|
||||
assertEquals(900, height)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `커뮤니티 이미지는 크기 정보가 없으면 높이를 계산하지 않는다`() {
|
||||
val height = calculateFeedCommunityImageHeight(
|
||||
containerWidthPx = 300,
|
||||
intrinsicWidthPx = 0,
|
||||
intrinsicHeightPx = 800
|
||||
)
|
||||
|
||||
assertNull(height)
|
||||
}
|
||||
}
|
||||
@@ -85,14 +85,15 @@ class FeedViewTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `community layout matches creator channel feed row structure`() {
|
||||
fun `community layout uses runtime image height instead of fixed crop height`() {
|
||||
val view = inflateView<FeedCommunityView>(R.layout.view_feed_community)
|
||||
val layout = projectFile("app/src/main/res/layout/view_feed_community.xml").readText()
|
||||
|
||||
assertFalse(layout.contains("@+id/tv_feed_community_keyword"))
|
||||
assertTrue(layout.contains("android:layout_width=\"match_parent\""))
|
||||
assertTrue(layout.contains("android:maxLines=\"5\""))
|
||||
assertTrue(layout.contains("android:layout_height=\"236dp\""))
|
||||
assertFalse(layout.contains("android:layout_height=\"236dp\""))
|
||||
assertTrue(layout.contains("android:scaleType=\"fitCenter\""))
|
||||
assertTrue(layout.contains("@drawable/bg_creator_channel_community_price"))
|
||||
assertTrue(layout.contains("@drawable/ic_bar_cash"))
|
||||
assertFalse(layout.contains("android:drawableStart=\"@drawable/ic_bar_cash\""))
|
||||
@@ -152,17 +153,21 @@ class FeedViewTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `community image container keeps creator channel fixed height`() {
|
||||
fun `community image container keeps fallback height until original image ratio is applied`() {
|
||||
val view = inflateView<FeedCommunityView>(R.layout.view_feed_community)
|
||||
val imageContainer = view.findViewById<FrameLayout>(R.id.fl_feed_community_image_container)
|
||||
|
||||
view.bind(sampleCommunityItem(bodyText = "본문", keywordText = "", imageUrl = "https://example.com/post.png"))
|
||||
view.measure(exactly(402.dpToPx()), View.MeasureSpec.UNSPECIFIED)
|
||||
|
||||
assertEquals(236.dpToPx(), imageContainer.measuredHeight)
|
||||
|
||||
view.applyCommunityImageSize(intrinsicWidthPx = 600, intrinsicHeightPx = 1800)
|
||||
view.measure(exactly(402.dpToPx()), View.MeasureSpec.UNSPECIFIED)
|
||||
|
||||
val expectedImageWidth = 402.dpToPx() - view.paddingLeft - view.paddingRight
|
||||
assertEquals(expectedImageWidth, imageContainer.measuredWidth)
|
||||
assertEquals(236.dpToPx(), imageContainer.measuredHeight)
|
||||
assertEquals(expectedImageWidth * 3, imageContainer.measuredHeight)
|
||||
assertEquals(true, imageContainer.clipToOutline)
|
||||
assertNotNull(imageContainer.outlineProvider)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user