From 9244a00713514ba3d502d6098239e9279f334621 Mon Sep 17 00:00:00 2001 From: klaus Date: Sun, 12 Jul 2026 20:51:30 +0900 Subject: [PATCH] =?UTF-8?q?fix(feed):=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=9B=90=EB=B3=B8?= =?UTF-8?q?=EB=B9=84=EC=9C=A8=20=EB=86=92=EC=9D=B4=EB=A5=BC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v2/widget/feed/FeedCommunityImageSize.kt | 12 ++++++ .../v2/widget/feed/FeedCommunityView.kt | 29 +++++++++++++ .../main/res/layout/view_feed_community.xml | 6 +-- .../widget/feed/FeedCommunityImageSizeTest.kt | 41 +++++++++++++++++++ .../sodalive/v2/widget/feed/FeedViewTest.kt | 13 ++++-- 5 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityImageSize.kt create mode 100644 app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityImageSizeTest.kt diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityImageSize.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityImageSize.kt new file mode 100644 index 00000000..afe28bca --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityImageSize.kt @@ -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() +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt index 3147cc14..a1ff3c43 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedCommunityView.kt @@ -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 } } diff --git a/app/src/main/res/layout/view_feed_community.xml b/app/src/main/res/layout/view_feed_community.xml index 2b58fede..de6ba22b 100644 --- a/app/src/main/res/layout/view_feed_community.xml +++ b/app/src/main/res/layout/view_feed_community.xml @@ -67,8 +67,9 @@ @@ -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" /> (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(R.layout.view_feed_community) val imageContainer = view.findViewById(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) }