Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸš€ 4단계 - μž₯λ°”κ΅¬λ‹ˆ(μˆ˜λŸ‰) #126

Open
wants to merge 4 commits into
base: sana-20
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@
- [x] μž₯λ°”κ΅¬λ‹ˆμ— λ”ν•˜κΈ° κΈ°λŠ₯ κ΅¬ν˜„
- [x] μž₯λ°”κ΅¬λ‹ˆ μˆ˜λŸ‰ 쑰절 κΈ°λŠ₯ κ΅¬ν˜„
- [x] μž₯λ°”κ΅¬λ‹ˆ μƒν’ˆ 제거 κΈ°λŠ₯ κ΅¬ν˜„
- [x] μž₯λ°”κ΅¬λ‹ˆ 화면에 λŒ€ν•œ ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±
- [x] μž₯λ°”κ΅¬λ‹ˆ 화면에 λŒ€ν•œ ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±


### step4 κΈ°λŠ₯ λͺ©λ‘
- [x] μƒν’ˆ λͺ©λ‘ ν™”λ©΄ μž₯λ°”κ΅¬λ‹ˆ λ”ν•˜κΈ° λ²„νŠΌ μΆ”κ°€
- [x] μƒν’ˆ λͺ©λ‘ ν™”λ©΄ μˆ˜λŸ‰ 쑰절 λ²„νŠΌ μΆ”κ°€
- [x] μˆ˜λŸ‰ 쑰절 κΈ°λŠ₯ κ΅¬ν˜„
- [x] μƒν’ˆ λͺ©λ‘, μž₯λ°”κ΅¬λ‹ˆ κ°„ μƒν’ˆ μˆ˜λŸ‰ 동기화 κΈ°λŠ₯ κ΅¬ν˜„


Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal class CartScreenTest {
composeTestRule.setContent {
ShoppingCartTheme {
CartScreen(
cartItems = Cart.items,
onClickBack = { },
onClickOrder = { },
)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/nextstep/shoppingcart/CartActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nextstep.shoppingcart
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import nextstep.shoppingcart.model.Cart
import nextstep.shoppingcart.screen.CartScreen
import nextstep.shoppingcart.ui.theme.ShoppingCartTheme

Expand All @@ -14,6 +15,7 @@ class CartActivity : ComponentActivity() {
setContent {
ShoppingCartTheme {
CartScreen(
cartItems = Cart.items,
onClickBack = {
finish()
},
Expand Down
16 changes: 8 additions & 8 deletions app/src/main/java/nextstep/shoppingcart/model/CartItem.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
package nextstep.shoppingcart.model

import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.snapshots.SnapshotStateList

data class CartItem(val product: Product, val count: Int) {
val totalPrice: Int get() = product.price * count
}

object Cart {
private val _items: MutableList<CartItem> = mutableListOf()
val items: List<CartItem> get() = _items.toList()
private val _items = mutableStateListOf<CartItem>()
val items: SnapshotStateList<CartItem> get() = _items
Comment on lines +11 to +12
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StateList와 SnapshotList둜 λ³€κ²½ν•˜μ‹  μ΄μœ κ°€ λ¬΄μ—‡μΈκ°€μš”?


val totalPrice: Int get() = _items.sumOf { it.totalPrice }

fun addOne(product: Product): List<CartItem> {
fun addOne(product: Product) {
val item = _items.find { it.product == product }
if (item == null) {
_items.add(CartItem(product, 1))
} else {
val index = _items.indexOf(item)
_items[index] = item.copy(count = item.count + 1)
}
return items
}

fun removeOne(product: Product): List<CartItem> {
fun removeOne(product: Product) {
_items.find { it.product == product }
?.let { item ->
if (item.count > 1) {
Expand All @@ -31,12 +33,10 @@ object Cart {
_items.remove(item)
}
}
return items
}

fun removeAll(product: Product): List<CartItem> {
fun removeAll(product: Product) {
_items.removeAll { it.product == product }
return items
}

fun getCount(product: Product): Int {
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/nextstep/shoppingcart/screen/CartScreen.kt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ €λ²ˆ λ―Έμ…˜μ—μ„œ #122 (comment) μ½”λ§¨νŠΈλ₯Ό μž‘μ„±ν–ˆλŠ”λ° 닡변이 κ°€λŠ₯ν•˜μ‹€κΉŒμš”?

Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import nextstep.shoppingcart.view.DefaultNavigationBackTopBar

@Composable
fun CartScreen(
cartItems: List<CartItem>,
onClickBack: () -> Unit,
onClickOrder: () -> Unit
) {
var cartItems by remember { mutableStateOf(Cart.items) }
val totalPrice by remember(cartItems) { mutableIntStateOf(Cart.totalPrice) }

Scaffold(
Expand All @@ -51,13 +51,13 @@ fun CartScreen(
.padding(paddingValues),
onClickOrder = onClickOrder,
onClickRemoveOne = { cartItem ->
cartItems = Cart.removeOne(cartItem.product)
Cart.removeOne(cartItem.product)
},
onClickAddOne = { cartItem ->
cartItems = Cart.addOne(cartItem.product)
Cart.addOne(cartItem.product)
},
onClickRemoveAll = { cartItem ->
cartItems = Cart.removeAll(cartItem.product)
Cart.removeAll(cartItem.product)
}
)
}
Expand Down
43 changes: 1 addition & 42 deletions app/src/main/java/nextstep/shoppingcart/view/CartProductItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -81,7 +80,7 @@ fun CartProductItem(
.align(Alignment.TopEnd)
.padding(top = 18.dp)
)
CartProductCount(
ProductCount(
count = cartItem.count,
onClickAddOne = onClickAddOne,
onClickRemoveOne = onClickRemoveOne,
Expand Down Expand Up @@ -123,46 +122,6 @@ private fun CartProductPrice(price: Int, modifier: Modifier = Modifier) {
)
}

@Composable
private fun CartProductCount(
count: Int,
onClickAddOne: () -> Unit,
onClickRemoveOne: () -> Unit,
modifier: Modifier = Modifier
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
) {
IconButton(
onClick = onClickRemoveOne,
modifier = Modifier.size(42.dp)
) {
Text(
text = "-",
fontSize = 22.sp,
fontWeight = FontWeight.Bold
)
}
Text(
text = count.toString(),
fontSize = 22.sp,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 18.dp)
)
IconButton(
onClick = onClickAddOne,
modifier = Modifier.size(42.dp)
) {
Text(
text = "+",
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
)
}
}
}

@Preview(showBackground = true)
@Composable
private fun CartProductItemPreview() {
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/nextstep/shoppingcart/view/ProductCount.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package nextstep.shoppingcart.view

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun ProductCount(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μž₯λ°”κ΅¬λ‹ˆ ν™”λ©΄μ—μ„œλ„ ProductCountλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ”λ°μš”.
μž₯λ°”κ΅¬λ‹ˆ ν™”λ©΄μ—μ„œ μƒν’ˆμ„ μ œκ±°ν•˜κ²Œ 되면 μƒν’ˆμ˜ 총합이 κ°±μ‹ λ˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.
μž₯λ°”κ΅¬λ‹ˆ ν™”λ©΄μ—μ„œ μƒν’ˆμ„ μ œκ±°ν–ˆμ„ 경우 μƒν’ˆμ˜ 총합이 갱신될 수 μžˆλ„λ‘ κ°œμ„ ν•΄λ³΄λ©΄ μ–΄λ–¨κΉŒμš”?

count: Int,
onClickAddOne: () -> Unit,
onClickRemoveOne: () -> Unit,
modifier: Modifier = Modifier
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
) {
IconButton(
onClick = onClickRemoveOne,
modifier = Modifier.size(42.dp)
) {
Text(
text = "-",
fontSize = 22.sp,
fontWeight = FontWeight.Bold
)
}
Comment on lines +28 to +37
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ λ²„νŠΌκ³Ό - λ²„νŠΌμ€ 곡톡점이 λ§Žμ€ 것 κ°™μŠ΅λ‹ˆλ‹€.
λ°˜λ³΅λ˜λŠ” λ·°λ₯Ό μž¬μ‚¬μš©ν•  수 μžˆλ„λ‘ κ°œμ„ ν•΄λ³΄λ©΄ μ–΄λ–¨κΉŒμš”?

Text(
text = count.toString(),
fontSize = 22.sp,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 18.dp)
)
IconButton(
onClick = onClickAddOne,
modifier = Modifier.size(42.dp)
) {
Text(
text = "+",
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
)
}
}
}

@Preview(showBackground = true)
@Composable
private fun CartProductCountPreview() {
ProductCount(
count = 2,
onClickAddOne = {},
onClickRemoveOne = {}
)
Comment on lines +60 to +64
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previewμ—λŠ” Interactive modeλΌλŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
Interactive modeλ₯Ό 톡해 + λ²„νŠΌκ³Ό - λ²„νŠΌμ΄ 잘 λ™μž‘ν•˜λŠ”μ§€ 확인할 수 μžˆλ„λ‘ κ°œμ„ ν•΄λ³΄λ©΄ μ–΄λ–¨κΉŒμš”?

}
84 changes: 73 additions & 11 deletions app/src/main/java/nextstep/shoppingcart/view/ProductsItem.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
package nextstep.shoppingcart.view

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
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.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
Expand All @@ -22,22 +34,51 @@ import nextstep.shoppingcart.model.Product
@Composable
fun ProductsItem(
product: Product,
onClick: (Product) -> Unit,
count: Int,
onClickItem: (Product) -> Unit,
onClickAdd: () -> Unit,
onClickAddOne: () -> Unit,
onclickRemoveOne: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
.width(158.dp)
.clickable {
onClick(product)
onClickItem(product)
}
) {
AsyncImage(
model = product.imageUrl,
contentDescription = "product image",
contentScale = ContentScale.Crop,
modifier = Modifier.aspectRatio(1f)
)
Box {
AsyncImage(
model = product.imageUrl,
contentDescription = "product image",
contentScale = ContentScale.Crop,
modifier = Modifier.aspectRatio(1f)
)
if (count > 0) {
ProductCount(
count = count,
onClickAddOne = onClickAddOne,
onClickRemoveOne = onclickRemoveOne,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 12.dp)
.background(Color.White, shape = RoundedCornerShape(4.dp))
)
} else {
IconButton(
onClick = onClickAdd,
modifier = Modifier
.padding(12.dp)
.align(Alignment.BottomEnd)
.clip(CircleShape)
.background(Color.White)
.size(42.dp)
) {
Icon(Icons.Filled.Add, null)
}
}
}
Spacer(
modifier = Modifier.height(8.dp)
)
Expand All @@ -58,15 +99,36 @@ fun ProductsItem(
}
}

@Preview
@Preview(showBackground = true)
@Composable
private fun ProductsItemCountZeroPreview() {
ProductsItem(
product = Product(
imageUrl = "",
name = "μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…",
price = 10000
),
count = 0,
onClickItem = {},
onClickAdd = {},
onClickAddOne = {},
onclickRemoveOne = {}
)
}

@Preview(showBackground = true)
@Composable
private fun ProductsItemPreview() {
private fun ProductsItemCountOnePreview() {
ProductsItem(
product = Product(
imageUrl = "",
name = "μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…μƒν’ˆλͺ…",
price = 10000
),
onClick = {}
count = 1,
onClickItem = {},
onClickAdd = {},
onClickAddOne = {},
onclickRemoveOne = {}
)
}
Loading