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

[스캇] 1, 2단계 쇼핑 장바구니 제출합니다. #14

Merged
merged 37 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1bfdd98
docs: 기능목록 작성
chws0508 May 9, 2023
f509529
feat : Product model 생성
chws0508 May 9, 2023
4f69db7
feat : Price model 생성
chws0508 May 9, 2023
72e3dcd
feat(ProductListActivity): 화면 xml 구현
chws0508 May 9, 2023
26fd65f
refactor: 도메인 패키지 변경
chws0508 May 9, 2023
5f01ba2
feat: default_image 추가
chws0508 May 9, 2023
9a60ad5
feat(ProductModel): 상품 UI Model 추가
chws0508 May 9, 2023
d15fa37
feat(Product): 상품 ID 추가
chws0508 May 9, 2023
5bcd6d1
feat(ProductListAdapter): 상품 목록 리사이클러뷰 어댑터 구현
chws0508 May 9, 2023
f20e472
feat(ProductDetail): 상품 상세 화면 UI 구현
chws0508 May 9, 2023
b797b4d
feat: Product Db 구현
chws0508 May 10, 2023
6f64b41
feat: ProductList 화면 구현
chws0508 May 10, 2023
6cc3101
refactor: 최근 본 상품 기능 수정
chws0508 May 10, 2023
85e1e7e
feat: Cart Db 구현
chws0508 May 10, 2023
0dc3c97
feat: ProductDetail 화면 구현
chws0508 May 10, 2023
e90310f
feat: Cart 화면 Xml 구현
chws0508 May 10, 2023
6e290d3
refactor: 변수명 변경
chws0508 May 10, 2023
72d5e9c
feat: Cart 화면 기능 구현
chws0508 May 10, 2023
a6b6594
refactor: RecyclerView 하나로 통합
chws0508 May 11, 2023
d69169c
feat: Products 기능 구현 및 테스트
chws0508 May 11, 2023
672e7e8
feat: 상품 리스트 더보기 기능 구현
chws0508 May 11, 2023
595cd6a
feat: 버튼 이미지 추가
chws0508 May 11, 2023
04c21fc
feat: 페이지 카운터 구현 및 Products 기능 추가
chws0508 May 11, 2023
298b992
feat: 장바구니 페이징 구현
chws0508 May 11, 2023
2f72956
docs: 기능 목록 업데이트
chws0508 May 11, 2023
fb76711
refactor: SpanSizeLookup 클래스명 변경
chws0508 May 13, 2023
f58d79a
refactor: presenter에서 초기화 작업 수행 및 !!사용하지 않도록 변경
chws0508 May 13, 2023
95a5f85
refactor: offset 기반으로 데이터를 가져오도록 수정 및 함수 분리
chws0508 May 13, 2023
88188d4
feat: Presenter 테스트 작성
chws0508 May 13, 2023
ab450da
feat: ProductDetail 화면 databinding 적용
chws0508 May 13, 2023
2f8bea2
feat: ProductList 화면 dataBinding 적용
chws0508 May 13, 2023
f8ab323
feat: CartActivity DataBinding 적용
chws0508 May 13, 2023
4f70545
fix: 테스트 코드 오류 수정
chws0508 May 13, 2023
3562d34
feat: ListAdapter 적용
chws0508 May 14, 2023
ebabe98
refactor: relaxed=true 를 적용하여 boilerPlate 코드 제거
chws0508 May 14, 2023
ae6957a
refactor: Paging 객체 생성 및 adapter 연결을 view 에서 하도록 변경
chws0508 May 15, 2023
da47316
refactor: ListAdapter적용 및 adapter 연결을 view 에서 하도록 변경
chws0508 May 15, 2023
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
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
# android-shopping-cart
# Shopping Cart

## ProductList
- [x] 최근 본 상품을 보여준다.
- [x] 앱이 종료되어도 데이터는 유지되어야 한다.
- [x] 최대 10개까지 확인할 수 있다.
- [x] 모든 상품을 보여준다.
- [x] 상품을 클릭하면 ProductDetail 화면으로 넘어간다.
- [x] 카트 아이콘을 누르면 Cart 화면으로 넘어간다.

## ProductDetail
- [x] 상품의 정보를 보여준다.
- [x] 장바구니 담기를 누르면 카트에 추가된다.
## Cart
- [x] 장바구니에 목록을 볼수있다.
- 장바구니 목록은 앱이종료되어도 유지되어야 한다.
- [x] 장바구니 목록을 삭제할 수 있다.

# Product
- [x] 상품 정보를 담고있다.


8 changes: 7 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-parcelize")
}

android {
Expand All @@ -22,7 +23,7 @@ android {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
}
}
Expand All @@ -33,14 +34,19 @@ android {
kotlinOptions {
jvmTarget = "11"
}
dataBinding {
enable = true
}
}

dependencies {
implementation(project(":domain"))
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.0")
implementation("com.google.android.material:material:1.7.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("com.github.bumptech.glide:glide:4.15.1")
}
11 changes: 10 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -10,9 +12,16 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Shopping"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".presentation.cart.CartActivity"
android:exported="false" />
<activity
android:name=".presentation.productdetail.ProductDetailActivity"
android:exported="false" />
<activity
android:name=".presentation.productlist.ProductListActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
11 changes: 0 additions & 11 deletions app/src/main/java/woowacourse/shopping/MainActivity.kt

This file was deleted.

56 changes: 56 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/cart/CartDbAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package woowacourse.shopping.data.cart

import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import java.lang.String.valueOf

class CartDbAdapter(db: CartDbHelper) : CartRepository {

private val writableDb: SQLiteDatabase = db.writableDatabase
override fun addCartProductId(productId: Int) {
val values = ContentValues().apply {
put(CartDbContract.PRODUCT_ID, productId)
put(CartDbContract.TIMESTAMP, System.currentTimeMillis())
}

writableDb.insert(CartDbContract.TABLE_NAME, null, values)
}

override fun deleteCartProductId(productId: Int) {
writableDb.delete(
CartDbContract.TABLE_NAME,
"${CartDbContract.PRODUCT_ID}=?",
arrayOf<String>(valueOf(productId)),
)
}

override fun getCartProductIds(): List<Int> {
val productIds = mutableListOf<Int>()

val cursor = writableDb.query(
CartDbContract.TABLE_NAME,
arrayOf(
CartDbContract.PRODUCT_ID,
CartDbContract.TIMESTAMP,
),
null,
null,
null,
null,
"${CartDbContract.TIMESTAMP} DESC",
null,
)
while (cursor.moveToNext()) {
val productId = cursor.getCartProductId()
productIds.add(productId)
}

cursor.close()

return productIds
}

private fun Cursor.getCartProductId(): Int =
getInt(getColumnIndexOrThrow(CartDbContract.PRODUCT_ID))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package woowacourse.shopping.data.cart

object CartDbContract {
const val TABLE_NAME = "cart"
const val PRODUCT_ID = "product_id"
const val TIMESTAMP = "timestamp"
}
28 changes: 28 additions & 0 deletions app/src/main/java/woowacourse/shopping/data/cart/CartDbHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package woowacourse.shopping.data.cart

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class CartDbHelper(
context: Context,
) : SQLiteOpenHelper(context, DB_NAME, null, 1) {

override fun onCreate(db: SQLiteDatabase?) {
db?.execSQL(
"CREATE TABLE ${CartDbContract.TABLE_NAME}(" +
"${CartDbContract.PRODUCT_ID} int," +
"${CartDbContract.TIMESTAMP} int" +
");",
)
}

override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db?.execSQL("DROP TABLE IF EXISTS ${CartDbContract.TABLE_NAME}")
onCreate(db)
}

companion object {
private const val DB_NAME = "cart.db"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package woowacourse.shopping.data.cart

interface CartRepository {
fun addCartProductId(productId: Int)
fun deleteCartProductId(productId: Int)
fun getCartProductIds(): List<Int>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package woowacourse.shopping.data.product

import woowacourse.shopping.Price
import woowacourse.shopping.Product

object MockProductRepository : ProductRepository {

override val products: List<Product> = getProducts(100)

private fun getProducts(size: Int): List<Product> {
return (1..size).map {
Product(
it,
"https://mediahub.seoul.go.kr/uploads/2016/09/952e8925ec41cc06e6164d695d776e51.jpg",
name = "상품$it",
price = Price((1000..100000).random()),
)
}
}

override fun findProductById(id: Int): Product? = products.find { it.id == id }

override fun getProductsWithRange(startIndex: Int, size: Int): List<Product> =
products.subList(startIndex, startIndex + size)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package woowacourse.shopping.data.product

import woowacourse.shopping.Product

interface ProductRepository {
val products: List<Product>
fun findProductById(id: Int): Product?
fun getProductsWithRange(startIndex: Int, size: Int): List<Product>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package woowacourse.shopping.data.recentproduct

object RecentProductDbContract {
const val TABLE_NAME = "recent_product"
const val PRODUCT_ID = "product_id"
const val TIMESTAMP = "timestamp"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package woowacourse.shopping.data.recentproduct

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class RecentProductDbHelper(
context: Context,
) : SQLiteOpenHelper(context, DB_NAME, null, 1) {

override fun onCreate(db: SQLiteDatabase?) {
db?.execSQL(
"CREATE TABLE ${RecentProductDbContract.TABLE_NAME}(" +
"${RecentProductDbContract.PRODUCT_ID} int," +
"${RecentProductDbContract.TIMESTAMP} int" +
");",
)
}

override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db?.execSQL("DROP TABLE IF EXISTS ${RecentProductDbContract.TABLE_NAME}")
onCreate(db)
}

companion object {
private const val DB_NAME = "recentProduct.db"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package woowacourse.shopping.data.recentproduct

import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import java.lang.String.valueOf

class RecentProductIdDbAdapter(db: RecentProductDbHelper) : RecentProductIdRepository {

private val writableDb: SQLiteDatabase = db.writableDatabase

override fun getRecentProductIds(size: Int): List<Int> {
val productIds = mutableListOf<Int>()

val cursor = writableDb.query(
RecentProductDbContract.TABLE_NAME,
arrayOf(
RecentProductDbContract.PRODUCT_ID,
RecentProductDbContract.TIMESTAMP,
),
null,
null,
null,
null,
"${RecentProductDbContract.TIMESTAMP} DESC",
null,
)
while (cursor.moveToNext() && (productIds.size < size)) {
val productId = cursor.getRecentProductId()
productIds.add(productId)
}

cursor.close()

return productIds
}

private fun Cursor.getRecentProductId(): Int =
getInt(getColumnIndexOrThrow(RecentProductDbContract.PRODUCT_ID))

override fun addRecentProductId(recentProductId: Int) {
val values = ContentValues().apply {
put(RecentProductDbContract.PRODUCT_ID, recentProductId)
put(RecentProductDbContract.TIMESTAMP, System.currentTimeMillis())
}

writableDb.insert(RecentProductDbContract.TABLE_NAME, null, values)
}

override fun deleteRecentProductId(recentProductId: Int) {
writableDb.delete(
RecentProductDbContract.TABLE_NAME,
"${RecentProductDbContract.PRODUCT_ID}=?",
arrayOf<String>(valueOf(recentProductId)),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package woowacourse.shopping.data.recentproduct

interface RecentProductIdRepository {

fun addRecentProductId(recentProductId: Int)

fun deleteRecentProductId(recentProductId: Int)
fun getRecentProductIds(size: Int): List<Int>
}
Loading