diff --git a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeItem.kt b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeItem.kt
index 571da9e..18e95e3 100644
--- a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeItem.kt
+++ b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeItem.kt
@@ -1,54 +1,113 @@
package com.sundaegukbap.banchango.feature.recipe.recommend
+import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.focus.focusModifier
+import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.res.imageResource
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight.Companion.Bold
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.TextUnit
+import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.compose.ui.util.lerp
import com.sundaegukbap.banchango.Recipe
import com.sundaegukbap.banchango.core.designsystem.component.NetworkImage
import com.sundaegukbap.banchango.core.designsystem.theme.BanchangoTheme
+import com.sundaegukbap.banchango.feature.reciperecommend.R
@Composable
fun RecipeItem(
recipeItemUiState: RecipeRecommendItemUiState,
+ pageOffset: Float,
onRecipeClick: (Recipe) -> Unit = {},
onRecipeLikeClick: (Recipe) -> Unit = {},
) {
Box(
modifier = Modifier
.fillMaxSize()
-
+ .graphicsLayer {
+ scaleX = lerp(
+ start = 0.9f,
+ stop = 1f,
+ fraction = 1f - pageOffset.coerceIn(0f, 1f)
+ )
+ scaleY = lerp(
+ start = 0.9f,
+ stop = 1f,
+ fraction = 1f - pageOffset.coerceIn(0f, 1f)
+ )
+ }
+ .clip(shape = RoundedCornerShape(44.dp))
+ .clickable {
+ onRecipeClick(recipeItemUiState.recipe)
+ }
) {
NetworkImage(
modifier = Modifier
- .clip(shape = RoundedCornerShape(32.dp))
- .fillMaxSize()
- .clickable {
- onRecipeClick(recipeItemUiState.recipe)
- },
+ .fillMaxSize(),
url = recipeItemUiState.recipe.image,
)
RecipeInfo(
recipeItemUiState.recipe,
modifier = Modifier.fillMaxSize(),
- onLikeClick = { onRecipeLikeClick(recipeItemUiState.recipe) }
)
+
+ RecipeIngredientCount(
+ modifier = Modifier
+ .align(Alignment.BottomStart),
+ have = recipeItemUiState.recipe.have.count(),
+ need = recipeItemUiState.recipe.need.count(),
+ imageSize = 95,
+ )
+
+ RecipeLikeButton(
+ modifier = Modifier
+ .align(Alignment.BottomEnd),
+ isLiked = recipeItemUiState.isLiked,
+ onLikeClick = { onRecipeLikeClick(recipeItemUiState.recipe) },
+ )
+
+ Box(
+ Modifier
+ .fillMaxSize()
+ .background(
+ color = Color.Black.copy(
+ alpha = lerp(
+ start = 0.5f,
+ stop = 0f,
+ fraction = 1f - pageOffset.coerceIn(0f, 1f)
+ )
+ ),
+ )
+ ) {
+
+ }
}
}
@@ -56,42 +115,58 @@ fun RecipeItem(
private fun RecipeInfo(
recipe: Recipe,
modifier: Modifier,
- onLikeClick: () -> Unit,
) {
Box(modifier = modifier) {
Text(
text = recipe.name,
color = Color.White,
- fontSize = 16.sp,
+ fontSize = 24.sp,
+ maxLines = 2,
+ minLines = 2,
style = TextStyle(fontWeight = Bold),
textAlign = TextAlign.Center,
modifier = Modifier
- .padding(horizontal = 24.dp, vertical = 12.dp)
- .clip(shape = RoundedCornerShape(32.dp))
- .background(Color.Black.copy(alpha = 0.5f))
+ .background(
+ brush = Brush.verticalGradient(listOf(Color.Black, Color.Transparent)),
+ alpha = 0.8f
+ )
.fillMaxWidth()
- .padding(16.dp),
+ .padding(top = 40.dp, bottom = 40.dp),
)
+ }
+}
- Text(
- text = "${recipe.have.count()} / ${recipe.need.count() + recipe.have.count()}",
- modifier = Modifier
- .align(Alignment.BottomStart)
- .padding(start = 24.dp, bottom = 24.dp),
- color = Color.White,
+@Composable
+fun RecipeLikeButton(
+ modifier: Modifier,
+ isLiked: Boolean,
+ onLikeClick: () -> Unit,
+) {
+ Box(
+ modifier = modifier
+ .clickable(
+ indication = null,
+ interactionSource = remember { MutableInteractionSource() },
+ onClick = onLikeClick
+ )
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.img_btn_right),
+ contentDescription = null,
+ modifier = Modifier.size(95.dp),
)
- Button(
+ Image(
+ painter = painterResource(id = if (isLiked) R.drawable.ic_heart_filled else R.drawable.ic_heart),
+ contentDescription = null,
modifier = Modifier
- .align(Alignment.BottomEnd)
- .padding(end = 24.dp, bottom = 12.dp),
- onClick = onLikeClick,
- ) {
- Text("좋아요")
- }
+ .size(32.dp)
+ .align(Alignment.Center)
+ .padding(top = 8.dp),
+ )
}
}
-@Preview(showBackground = true)
+@Preview(showBackground = false)
@Composable
fun RecipeItemPreview() {
BanchangoTheme {
@@ -112,6 +187,43 @@ fun RecipeItemPreview() {
),
isLiked = true,
),
+ pageOffset = 0f,
)
}
}
+
+@Composable
+fun RecipeIngredientCount(
+ modifier: Modifier,
+ imageSize: Int,
+ have: Int,
+ need: Int,
+) {
+ Box(modifier = modifier) {
+ Image(
+ modifier = Modifier.size(imageSize.dp),
+ painter = painterResource(id = R.drawable.img_wave),
+ contentDescription = null,
+ )
+ Text(
+ text = "$have / ${need + have}",
+ modifier = Modifier
+ .padding(top = 32.dp)
+ .align(Alignment.Center),
+ color = Color.White,
+ style = TextStyle(
+ letterSpacing = 0.1.sp,
+ fontWeight = Bold,
+ fontSize = 20.sp
+ ),
+ )
+ }
+}
+
+@Preview(showBackground = false)
+@Composable
+fun RecipeIngredientCountPreview() {
+ BanchangoTheme {
+ RecipeIngredientCount(modifier = Modifier, have = 3, need = 7, imageSize = 120)
+ }
+}
diff --git a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeRecommendViewModel.kt b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeRecommendViewModel.kt
index f77ffaf..c0efaba 100644
--- a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeRecommendViewModel.kt
+++ b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipeRecommendViewModel.kt
@@ -22,11 +22,12 @@ class RecipeRecommendViewModel @Inject constructor(
init {
viewModelScope.launch {
- recipeRepository.getRecipeRecommendation().onSuccess { recipes ->
- _uiState.value = RecipeRecommendUiState.Success(recipes.toUiState())
- }.onFailure { throwable ->
- throwable.printStackTrace()
- }
+ recipeRepository.getRecipeRecommendation()
+ .onSuccess { recipes ->
+ _uiState.value = RecipeRecommendUiState.Success(recipes.toUiState())
+ }.onFailure { throwable ->
+ throwable.printStackTrace()
+ }
}
}
@@ -49,7 +50,7 @@ class RecipeRecommendViewModel @Inject constructor(
val successUiState = _uiState.value as? RecipeRecommendUiState.Success ?: return
val likedRecipeUiStates = successUiState.recipes.map { recipeUiState ->
if (recipeUiState.recipe.id == recipe.id) {
- recipeUiState.copy(isLiked = true)
+ recipeUiState.copy(isLiked = !recipeUiState.isLiked)
} else {
recipeUiState
}
diff --git a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipesRecommendScreen.kt b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipesRecommendScreen.kt
index f96f44a..463b29d 100644
--- a/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipesRecommendScreen.kt
+++ b/Android/feature/recipe/src/main/java/com/sundaegukbap/banchango/feature/recipe/recommend/RecipesRecommendScreen.kt
@@ -18,6 +18,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sundaegukbap.banchango.Recipe
import com.sundaegukbap.banchango.core.designsystem.theme.BanchangoTheme
+import kotlin.math.absoluteValue
@Composable
fun RecipeRecommendRoute(
@@ -92,10 +93,13 @@ private fun RecipeRecommendScreen(
if (page >= recipeRecommends.size - 2) {
onLastPageVisible()
}
+ val pageOffset =
+ (pagerState.currentPage - page + pagerState.currentPageOffsetFraction).absoluteValue
RecipeItem(
recipeItemUiState = recipeRecommends[page],
onRecipeClick = onRecipeClick,
onRecipeLikeClick = onLikeClick,
+ pageOffset = pageOffset,
)
}
}
diff --git a/Android/feature/recipe/src/main/res/drawable/ic_heart.xml b/Android/feature/recipe/src/main/res/drawable/ic_heart.xml
new file mode 100644
index 0000000..c7181cd
--- /dev/null
+++ b/Android/feature/recipe/src/main/res/drawable/ic_heart.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/Android/feature/recipe/src/main/res/drawable/ic_heart_filled.xml b/Android/feature/recipe/src/main/res/drawable/ic_heart_filled.xml
new file mode 100644
index 0000000..cb9cbf8
--- /dev/null
+++ b/Android/feature/recipe/src/main/res/drawable/ic_heart_filled.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/Android/feature/recipe/src/main/res/drawable/img_btn_right.xml b/Android/feature/recipe/src/main/res/drawable/img_btn_right.xml
new file mode 100644
index 0000000..c44994e
--- /dev/null
+++ b/Android/feature/recipe/src/main/res/drawable/img_btn_right.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/Android/feature/recipe/src/main/res/drawable/img_wave.xml b/Android/feature/recipe/src/main/res/drawable/img_wave.xml
new file mode 100644
index 0000000..166c514
--- /dev/null
+++ b/Android/feature/recipe/src/main/res/drawable/img_wave.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+