diff --git a/week2/.idea/deviceManager.xml b/week2/.idea/deviceManager.xml
new file mode 100644
index 0000000..91f9558
--- /dev/null
+++ b/week2/.idea/deviceManager.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/week2/.idea/misc.xml b/week2/.idea/misc.xml
index 74dd639..34e8f59 100644
--- a/week2/.idea/misc.xml
+++ b/week2/.idea/misc.xml
@@ -7,4 +7,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/week2/app/build.gradle.kts b/week2/app/build.gradle.kts
index 4d5cf39..6a859c7 100644
--- a/week2/app/build.gradle.kts
+++ b/week2/app/build.gradle.kts
@@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
+ id("kotlin-parcelize")
}
android {
diff --git a/week2/app/src/main/java/com/example/week2/HomeFragment.kt b/week2/app/src/main/java/com/example/week2/HomeFragment.kt
index 316bc0b..6905b6a 100644
--- a/week2/app/src/main/java/com/example/week2/HomeFragment.kt
+++ b/week2/app/src/main/java/com/example/week2/HomeFragment.kt
@@ -5,6 +5,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import androidx.recyclerview.widget.LinearLayoutManager
import com.example.week2.databinding.FragmentHomeBinding
class HomeFragment : Fragment() {
@@ -19,6 +21,41 @@ class HomeFragment : Fragment() {
return binding.root
}
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupRecyclerView()
+ }
+
+ private fun setupRecyclerView() {
+ val dummyProducts = listOf(
+ Product(1, "Air Jordan XXXVI", "Basketball Shoes", "US$185", R.drawable.img_air_jordan_xxxvi, category = "Basketball Shoes"),
+ Product(2, "Nike Air Force 1 '07", "Men's Shoes", "US$115", R.drawable.img_nike_air_force, category = "Men's Shoes"),
+ Product(3, "Nike Everyday Plus Cushioned", "Training Socks", "US$20", R.drawable.img_nike_everyday_plus_cushioned, category = "Training Socks")
+ )
+
+ val adapter = ProductAdapter(
+ dummyProducts,
+ onItemClick = { product ->
+ navigateToDetail(product)
+ },
+ onWishlistClick = { product, position ->
+ product.isWishlisted = !product.isWishlisted
+ binding.rvHomeProducts.adapter?.notifyItemChanged(position)
+ }
+ )
+
+ binding.rvHomeProducts.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
+ binding.rvHomeProducts.adapter = adapter
+ }
+
+ private fun navigateToDetail(product: Product) {
+ // Navigation Component를 사용하여 상세 화면으로 이동
+ val bundle = Bundle().apply {
+ putParcelable("product", product)
+ }
+ findNavController().navigate(R.id.action_homeFragment_to_productDetailFragment, bundle)
+ }
+
override fun onDestroyView() {
super.onDestroyView()
_binding = null
diff --git a/week2/app/src/main/java/com/example/week2/Product.kt b/week2/app/src/main/java/com/example/week2/Product.kt
new file mode 100644
index 0000000..3a45829
--- /dev/null
+++ b/week2/app/src/main/java/com/example/week2/Product.kt
@@ -0,0 +1,15 @@
+package com.example.week2
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class Product(
+ val id: Int,
+ val name: String,
+ val description: String,
+ val price: String,
+ val imageResId: Int,
+ var isWishlisted: Boolean = false,
+ val category: String = ""
+) : Parcelable
diff --git a/week2/app/src/main/java/com/example/week2/ProductAdapter.kt b/week2/app/src/main/java/com/example/week2/ProductAdapter.kt
new file mode 100644
index 0000000..9761741
--- /dev/null
+++ b/week2/app/src/main/java/com/example/week2/ProductAdapter.kt
@@ -0,0 +1,45 @@
+package com.example.week2
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.week2.databinding.ItemProductBinding
+
+class ProductAdapter(
+ private val products: List,
+ private val onItemClick: (Product) -> Unit,
+ private val onWishlistClick: (Product, Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class ProductViewHolder(private val binding: ItemProductBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(product: Product) {
+ binding.tvProductName.text = product.name
+ binding.tvProductDesc.text = product.description
+ binding.tvProductPrice.text = product.price
+ binding.ivProductImage.setImageResource(product.imageResId)
+
+ val heartRes = if (product.isWishlisted) {
+ R.drawable.ic_heart_fill
+ } else {
+ R.drawable.ic_heart_empty
+ }
+ binding.ibWishlist.setImageResource(heartRes)
+
+ binding.root.setOnClickListener { onItemClick(product) }
+ binding.ibWishlist.setOnClickListener { onWishlistClick(product, adapterPosition) }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
+ val binding = ItemProductBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return ProductViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
+ holder.bind(products[position])
+ }
+
+ override fun getItemCount(): Int = products.size
+}
diff --git a/week2/app/src/main/java/com/example/week2/ProductDetailFragment.kt b/week2/app/src/main/java/com/example/week2/ProductDetailFragment.kt
new file mode 100644
index 0000000..ffd72c3
--- /dev/null
+++ b/week2/app/src/main/java/com/example/week2/ProductDetailFragment.kt
@@ -0,0 +1,58 @@
+package com.example.week2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import com.example.week2.databinding.FragmentProductDetailBinding
+
+class ProductDetailFragment : Fragment() {
+ private var _binding: FragmentProductDetailBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = FragmentProductDetailBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val product = arguments?.getParcelable("product")
+
+ product?.let {
+ binding.tvHeaderTitle.text = it.name
+ binding.ivDetailImage.setImageResource(it.imageResId)
+ binding.tvDetailCategory.text = it.category
+ binding.tvDetailName.text = it.name
+ binding.tvDetailPrice.text = it.price
+
+ updateWishlistButton(it.isWishlisted)
+ }
+
+ binding.ibBack.setOnClickListener {
+ findNavController().popBackStack()
+ }
+
+ binding.btnWishlist.setOnClickListener {
+ product?.let {
+ it.isWishlisted = !it.isWishlisted
+ updateWishlistButton(it.isWishlisted)
+ }
+ }
+ }
+
+ private fun updateWishlistButton(isWishlisted: Boolean) {
+ binding.ivWishlistHeart.isSelected = isWishlisted
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
diff --git a/week2/app/src/main/java/com/example/week2/PurchaseFragment.kt b/week2/app/src/main/java/com/example/week2/PurchaseFragment.kt
index 6e9ae28..fec46e5 100644
--- a/week2/app/src/main/java/com/example/week2/PurchaseFragment.kt
+++ b/week2/app/src/main/java/com/example/week2/PurchaseFragment.kt
@@ -5,6 +5,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import androidx.recyclerview.widget.GridLayoutManager
import com.example.week2.databinding.FragmentPurchaseBinding
class PurchaseFragment : Fragment() {
@@ -19,6 +21,42 @@ class PurchaseFragment : Fragment() {
return binding.root
}
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupRecyclerView()
+ }
+
+ private fun setupRecyclerView() {
+ val dummyProducts = listOf(
+ Product(1, "Nike Everyday Plus Cushioned", "Training Crew Socks (6 Pairs)", "US$10", R.drawable.img_nike_everyday_plus_cushioned, category = "Training Crew Socks"),
+ Product(2, "Nike Elite Crew", "Basketball Socks", "US$16", R.drawable.img_training_ankle_socks, category = "Basketball Socks"),
+ Product(3, "Nike Air Force 1 '07", "Women's Shoes", "US$115", R.drawable.img_nike_air_force, category = "Women's Shoes"),
+ Product(4, "Jordan Nike Air Force 1 '07 Essentials", "Men's Shoes", "US$115", R.drawable.img_air_jordan_xxxvi, category = "Men's Shoes")
+ )
+
+ val adapter = ProductAdapter(
+ dummyProducts,
+ onItemClick = { product ->
+ navigateToDetail(product)
+ },
+ onWishlistClick = { product, position ->
+ product.isWishlisted = !product.isWishlisted
+ binding.rvPurchaseProducts.adapter?.notifyItemChanged(position)
+ }
+ )
+
+ binding.rvPurchaseProducts.layoutManager = GridLayoutManager(context, 2)
+ binding.rvPurchaseProducts.adapter = adapter
+ }
+
+ private fun navigateToDetail(product: Product) {
+ // Navigation Component를 사용하여 상세 화면으로 이동
+ val bundle = Bundle().apply {
+ putParcelable("product", product)
+ }
+ findNavController().navigate(R.id.action_purchaseFragment_to_productDetailFragment, bundle)
+ }
+
override fun onDestroyView() {
super.onDestroyView()
_binding = null
diff --git a/week2/app/src/main/java/com/example/week2/WishlistFragment.kt b/week2/app/src/main/java/com/example/week2/WishlistFragment.kt
index 44f97db..000b4a4 100644
--- a/week2/app/src/main/java/com/example/week2/WishlistFragment.kt
+++ b/week2/app/src/main/java/com/example/week2/WishlistFragment.kt
@@ -4,7 +4,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Toast
import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.GridLayoutManager
import com.example.week2.databinding.FragmentWishlistBinding
class WishlistFragment : Fragment() {
@@ -19,6 +21,39 @@ class WishlistFragment : Fragment() {
return binding.root
}
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupRecyclerView()
+ }
+
+ private fun setupRecyclerView() {
+ // Dummy wishlist data
+ val dummyWishlist = mutableListOf(
+ Product(1, "Nike Everyday Plus Cushioned", "Training Ankle Socks (6 Pairs)", "US$16", R.drawable.img_training_ankle_socks, true),
+ Product(2, "Air Jordan XXXVI", "Basketball Shoes", "US$185", R.drawable.img_air_jordan_xxxvi, true)
+ )
+
+ val adapter = ProductAdapter(
+ dummyWishlist,
+ onItemClick = { product ->
+ Toast.makeText(context, "${product.name} clicked", Toast.LENGTH_SHORT).show()
+ },
+ onWishlistClick = { product, position ->
+ product.isWishlisted = !product.isWishlisted
+ // In wishlist fragment, usually removing from wishlist means removing from the list
+ if (!product.isWishlisted) {
+ dummyWishlist.removeAt(position)
+ binding.rvWishlistProducts.adapter?.notifyItemRemoved(position)
+ } else {
+ binding.rvWishlistProducts.adapter?.notifyItemChanged(position)
+ }
+ }
+ )
+
+ binding.rvWishlistProducts.layoutManager = GridLayoutManager(context, 2)
+ binding.rvWishlistProducts.adapter = adapter
+ }
+
override fun onDestroyView() {
super.onDestroyView()
_binding = null
diff --git a/week2/app/src/main/res/drawable/bg_black_round.xml b/week2/app/src/main/res/drawable/bg_black_round.xml
new file mode 100644
index 0000000..fcc2357
--- /dev/null
+++ b/week2/app/src/main/res/drawable/bg_black_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/bg_white_stroke.xml b/week2/app/src/main/res/drawable/bg_white_stroke.xml
new file mode 100644
index 0000000..4f8e667
--- /dev/null
+++ b/week2/app/src/main/res/drawable/bg_white_stroke.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/ic_caretleft.xml b/week2/app/src/main/res/drawable/ic_caretleft.xml
new file mode 100644
index 0000000..1912c2d
--- /dev/null
+++ b/week2/app/src/main/res/drawable/ic_caretleft.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/ic_heart_empty.xml b/week2/app/src/main/res/drawable/ic_heart_empty.xml
new file mode 100644
index 0000000..a7904b5
--- /dev/null
+++ b/week2/app/src/main/res/drawable/ic_heart_empty.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/ic_heart_fill.xml b/week2/app/src/main/res/drawable/ic_heart_fill.xml
new file mode 100644
index 0000000..91664d4
--- /dev/null
+++ b/week2/app/src/main/res/drawable/ic_heart_fill.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/ic_heart_filled.xml b/week2/app/src/main/res/drawable/ic_heart_filled.xml
new file mode 100644
index 0000000..67df58b
--- /dev/null
+++ b/week2/app/src/main/res/drawable/ic_heart_filled.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/ic_magnifyingglass.xml b/week2/app/src/main/res/drawable/ic_magnifyingglass.xml
new file mode 100644
index 0000000..9077a42
--- /dev/null
+++ b/week2/app/src/main/res/drawable/ic_magnifyingglass.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/img_air_jordan_xxxvi.png b/week2/app/src/main/res/drawable/img_air_jordan_xxxvi.png
new file mode 100644
index 0000000..19129df
Binary files /dev/null and b/week2/app/src/main/res/drawable/img_air_jordan_xxxvi.png differ
diff --git a/week2/app/src/main/res/drawable/img_nike_air_force.png b/week2/app/src/main/res/drawable/img_nike_air_force.png
new file mode 100644
index 0000000..1fc5039
Binary files /dev/null and b/week2/app/src/main/res/drawable/img_nike_air_force.png differ
diff --git a/week2/app/src/main/res/drawable/img_nike_everyday_plus_cushioned.png b/week2/app/src/main/res/drawable/img_nike_everyday_plus_cushioned.png
new file mode 100644
index 0000000..9a23c22
Binary files /dev/null and b/week2/app/src/main/res/drawable/img_nike_everyday_plus_cushioned.png differ
diff --git a/week2/app/src/main/res/drawable/img_training_ankle_socks.png b/week2/app/src/main/res/drawable/img_training_ankle_socks.png
new file mode 100644
index 0000000..04a81da
Binary files /dev/null and b/week2/app/src/main/res/drawable/img_training_ankle_socks.png differ
diff --git a/week2/app/src/main/res/drawable/sl_item_wishlist_icon.xml b/week2/app/src/main/res/drawable/sl_item_wishlist_icon.xml
new file mode 100644
index 0000000..7ca06ad
--- /dev/null
+++ b/week2/app/src/main/res/drawable/sl_item_wishlist_icon.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/sl_wishlist_icon.xml b/week2/app/src/main/res/drawable/sl_wishlist_icon.xml
new file mode 100644
index 0000000..3e176b9
--- /dev/null
+++ b/week2/app/src/main/res/drawable/sl_wishlist_icon.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/drawable/sl_wishlist_tint.xml b/week2/app/src/main/res/drawable/sl_wishlist_tint.xml
new file mode 100644
index 0000000..78fdb7c
--- /dev/null
+++ b/week2/app/src/main/res/drawable/sl_wishlist_tint.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/week2/app/src/main/res/layout/activity_main.xml b/week2/app/src/main/res/layout/activity_main.xml
index 7570451..376288c 100644
--- a/week2/app/src/main/res/layout/activity_main.xml
+++ b/week2/app/src/main/res/layout/activity_main.xml
@@ -30,4 +30,4 @@
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
-
+
\ No newline at end of file
diff --git a/week2/app/src/main/res/layout/fragment_cart.xml b/week2/app/src/main/res/layout/fragment_cart.xml
index 4ad1697..2c8bfbd 100644
--- a/week2/app/src/main/res/layout/fragment_cart.xml
+++ b/week2/app/src/main/res/layout/fragment_cart.xml
@@ -23,7 +23,7 @@
android:layout_marginTop="20dp"
android:gravity="center"
android:text="@string/cart_empty_msg"
- android:textColor="@android:color/black"
+ android:textColor="@color/text_main"
app:layout_constraintBottom_toTopOf="@+id/btn_order"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -34,9 +34,9 @@
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="20dp"
- android:backgroundTint="@android:color/black"
+ android:backgroundTint="@color/primary_black"
android:text="@string/cart_order"
- android:textColor="@android:color/white"
+ android:textColor="@color/primary_white"
app:cornerRadius="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/week2/app/src/main/res/layout/fragment_home.xml b/week2/app/src/main/res/layout/fragment_home.xml
index 34e9993..ec2cee4 100644
--- a/week2/app/src/main/res/layout/fragment_home.xml
+++ b/week2/app/src/main/res/layout/fragment_home.xml
@@ -1,41 +1,83 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/layout/fragment_product_detail.xml b/week2/app/src/main/res/layout/fragment_product_detail.xml
new file mode 100644
index 0000000..8449634
--- /dev/null
+++ b/week2/app/src/main/res/layout/fragment_product_detail.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/layout/fragment_purchase.xml b/week2/app/src/main/res/layout/fragment_purchase.xml
index 9f448ec..6b9f054 100644
--- a/week2/app/src/main/res/layout/fragment_purchase.xml
+++ b/week2/app/src/main/res/layout/fragment_purchase.xml
@@ -1,20 +1,23 @@
-
+ android:layout_height="match_parent">
+ app:tabRippleColor="@android:color/transparent"
+ app:tabIndicatorFullWidth="false"
+ app:tabIndicatorHeight="2dp"
+ app:layout_constraintTop_toTopOf="parent">
-
+
+
+
diff --git a/week2/app/src/main/res/layout/fragment_wishlist.xml b/week2/app/src/main/res/layout/fragment_wishlist.xml
index 86902d3..85b569c 100644
--- a/week2/app/src/main/res/layout/fragment_wishlist.xml
+++ b/week2/app/src/main/res/layout/fragment_wishlist.xml
@@ -1,16 +1,32 @@
-
+ android:layout_height="match_parent">
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
-
+
+
+
diff --git a/week2/app/src/main/res/layout/item_product.xml b/week2/app/src/main/res/layout/item_product.xml
new file mode 100644
index 0000000..e31b2f5
--- /dev/null
+++ b/week2/app/src/main/res/layout/item_product.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/week2/app/src/main/res/navigation/nav_graph.xml b/week2/app/src/main/res/navigation/nav_graph.xml
index 1bf08d3..348654c 100644
--- a/week2/app/src/main/res/navigation/nav_graph.xml
+++ b/week2/app/src/main/res/navigation/nav_graph.xml
@@ -9,12 +9,20 @@
android:id="@+id/nav_home"
android:name="com.example.week2.HomeFragment"
android:label="HomeFragment"
- tools:layout="@layout/fragment_home" />
+ tools:layout="@layout/fragment_home">
+
+
+ tools:layout="@layout/fragment_purchase">
+
+
+
+
+
diff --git a/week2/app/src/main/res/values/colors.xml b/week2/app/src/main/res/values/colors.xml
index f8c6127..5af3ead 100644
--- a/week2/app/src/main/res/values/colors.xml
+++ b/week2/app/src/main/res/values/colors.xml
@@ -1,10 +1,26 @@
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
+
#FF000000
#FFFFFFFF
-
\ No newline at end of file
+
+
+ #111111
+ #FFFFFF
+ #E2112C
+ #111111
+ #757575
+ #BDBDBD
+ #F6F6F6
+ #E0E0E0
+ #444444
+ #757575
+ #F6F6F6
+
+
+ #111111
+ #757575
+
+
+ #E2112C
+
diff --git a/week2/app/src/main/res/values/strings.xml b/week2/app/src/main/res/values/strings.xml
index 29a13de..f28f503 100644
--- a/week2/app/src/main/res/values/strings.xml
+++ b/week2/app/src/main/res/values/strings.xml
@@ -26,4 +26,12 @@
위시리스트
+
+
+ The Nike Everyday Plus Cushioned Socks bring comfort to your workout with extra cushioning under the heel and forefoot and a snug, supportive arch band. Sweat-wicking power and breathability up top help keep your feet dry and cool to help push you through that extra set.
+ 위시리스트
+ • Shown: Multi-Color\n• Style: SX6897-965
+ View Product Details
+ 사이즈 선택
+ 장바구니에 추가