From 3b598ddcb50cb4a4b69453c22e3cca311ae38b2c Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 11:21:57 +0900 Subject: [PATCH 01/31] =?UTF-8?q?Docs[README.md]:=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=EB=AF=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index df2a6477..585b9b2f 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # android-map-keyword +# 1단계 + +## 기능 요구 사항 +- 카카오맵 클론 코딩을 위한 시작입니다. +- 검색어 입력 및 검색 결과를 표시할 기본 레이아웃을 구현한다. +- 검색에 사용될 데이터를 로컬 데이터베이스에 생성한다. + +## 프로그래밍 요구 사항 +- 검색 데이터는 저장은 SQLite를 사용한다. +- 가능한 MVVM 아키텍처 패턴을 적용하도록 한다. +- 코드 컨벤션을 준수하며 프로그래밍한다. From 2c41560c3d3d9105440bae97a3c43008fec87f24 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 11:53:27 +0900 Subject: [PATCH 02/31] =?UTF-8?q?Design:=20=EC=83=9D=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=99=94=EB=A9=B4=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/drawable/x.png | Bin 0 -> 3272 bytes app/src/main/res/layout/activity_main.xml | 27 +++++++++++++++++++++- app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable/x.png diff --git a/app/src/main/res/drawable/x.png b/app/src/main/res/drawable/x.png new file mode 100644 index 0000000000000000000000000000000000000000..15dcc1b30d4600ed72662dd5ce653f5f499fdea1 GIT binary patch literal 3272 zcmeHJdsGu=7M~0qr9{fIg~Y0nuJo+9JS`r@3Qeq_QV}TOAQ&`3Er_xt5GtVJjPxPY zuC!aK(5!@3UMeCFc_Rr6f(n=j3sM1xhsZmDk`NM-naxZ+J@(jh_Uy`^JLlxwFW>#$ z-|yaU?)}cB`upxOH(O-}0D!soZqEP!0F6r!Ff}on#=Lj#8jXqY1MfgnQ`6o-zX9Xl z*9E&ngaBX>M*JuR%=}2>=38-I!EtPUcwBr~?8iWSe7sX+^l{UD}Zn@jq)-HS4(b@e|Z(sitbYO63`041_#N@O>IjdRF3iGQ%0KiP>?YTWL;qi3; zI4Avc`nlP|6>`~T)BE?|wa!i2$caQXau;*<_D=CPLJYrj+l3v6gk+r?U7;}~$v*i) z+ZXEa=#Ed**CG#W#Ba3w(Z%{iWv0MuUUdp}xN$?gINmy3Hodk+qvp7QT*=zH7{JMYzqPi~{rdJxq63Oge-5$dUhG_7 zh8C>}{Gpan*Fhh78aJ1pwZ9dcbR3g+(N2o83q872R}CU9hqWDVD>rO=#-~6AkrQtZ zOtl+BqbR)#5%U+uOFFl8_b$t=1}oH+NHW%L?Se=kD;575a#rt{oejG}E5^t`J05;4 z5AwMNKby#a+_zQ{C|PJyYzqOy6QC921gvEP?X$nU3 zm&57c&Ur$qkv`LO$A{YEfo0OgJsZiOP|9H)5fo;&vX=<5ILI;~gXG|%l}R| zl>1o62?1OI?pMjC7+taHjOp@}(h?-dK$O)CuH7b%q&VPhb7}qVYN>N3jWs9JkDP`1 zN#93O-0?O)e&5NhonQ)<>AcHx%0onxs$^xSY=_Eys61UnJsMP^T4YrKdHDEpzB^KV zoyJm0bSS*c9W4X0V5OF0ai{@Iz*av|bb&n>jispsYT!#y8{05yujK&!C^+_fR|3fm zj);O!iG!)xi?8Hj&;&_zD;GFv=mp035a~Df)XdUT`Xy5NrI;7eK21r06DYbes$6^k z!7kGURjq!D#n>3AilApRYXQSg(3s4L1)um8Gqr>+w;Vi&F4zrI|FHZY zvZ(_MgOG6+bQ}buWlNT5IsD6kE#+a5Z{RnCeBc3}^1ueXELm3Ld!lfW`5J?Lc4{fQ z?WI0=p?&2|7krE1aAiUAkyq~Omv!uh(a8|tF&x$a$}vX0wh&66G0v9+imTHW8EPGP z2XS!er;Eq~d8WVVmjj=JLdB0H#>@Qq=pI(yJ+f#VG)n_@;gu%%lfJu-@Qi}y)US^sI%&P(d`G(n=S*(Bq= zTxJ=%OH1r`o92(`R;^E@D=<9YLF!m9!`p55k8iC>lT4V=I}I*$-%T zMKeSPABuyd_f^v^`yE+$G8CoamjebWO^^?thsLSIM;&;osN-~8yr2>4=9+gzsK*CO7<}?CUq2U)2@h&Ow4wAS* zzj^~fykY`nQFL?%o&YbQ$|XEX<3d^pfd_Rx=NS;F-+;oMh@%UsU`;GqTf$!?= zn9Rq`C5y~);jzS^&z-jPDs!`#)so!f&QG-0N+0?9M9Qc0d_!wZM%vC#ALw12m{xA8 zuc`7w6qWoK_2zW;O~qd|eQhGHzN+-h_|r<8H8a&WOHFJ}pZd8&cR!6=x7Bs(9A*+7 W(6f^&lH?Fy(B59Yo<$$ + + + + + + + Map + 검색어를 입력해 주세요. + 검색 결과가 없습니다. \ No newline at end of file From 4f9066a96749365402a6cfa23f8112d127b87f87 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 14:43:24 +0900 Subject: [PATCH 03/31] =?UTF-8?q?Feat:=20=EC=83=9D=EC=84=B1=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=B2=A0=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../campus/tech/kakao/map/MainActivity.kt | 32 +++++++++++++++++++ .../campus/tech/kakao/map/PlaceContract.kt | 10 ++++++ .../campus/tech/kakao/map/PlaceDbHelper.kt | 21 ++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 app/src/main/java/campus/tech/kakao/map/PlaceContract.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 95b43803..c17e4001 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -1,11 +1,43 @@ package campus.tech.kakao.map +import android.content.ContentValues import android.os.Bundle +import android.util.Log import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + val db = PlaceDbHelper(this) + val writableDatabase = db.writableDatabase + val values = ContentValues() + values.put(PlaceContract.COLUMN_NAME_NAME, "카페1") + values.put(PlaceContract.COLUMN_NAME_ADDRESS, "서울시 강남구") + + writableDatabase.insert(PlaceContract.TABLE_NAME, null, values) + + val readableDatabase = db.readableDatabase + var searchResult = "%카페%" + val cursor = readableDatabase.query( + PlaceContract.TABLE_NAME, + arrayOf(PlaceContract.COLUMN_NAME_NAME), + "${PlaceContract.COLUMN_NAME_NAME} like ?", + arrayOf(searchResult), + null, + null, + "${PlaceContract.COLUMN_NAME_NAME} DESC" + ) + + val result = mutableListOf() + while (cursor.moveToNext()) { + result.add( + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_NAME) + ) + ) + } + cursor.close() } } diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt new file mode 100644 index 00000000..e8d1aff1 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt @@ -0,0 +1,10 @@ +package campus.tech.kakao.map + +import android.provider.BaseColumns + +object PlaceContract:BaseColumns { + const val TABLE_NAME = "place" + const val COLUMN_NAME_NAME = "name" + const val COLUMN_NAME_ADDRESS = "address" + const val COLUMN_NAME_TYPE = "type" +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt new file mode 100644 index 00000000..f9eacb1c --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -0,0 +1,21 @@ +package campus.tech.kakao.map + +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper + +class PlaceDbHelper(context: Context):SQLiteOpenHelper( + context, "place.db", null, 1) { + override fun onCreate(db: SQLiteDatabase?) { + db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + + "(id INTEGER PRIMARY KEY, " + + "${PlaceContract.COLUMN_NAME_NAME} TEXT, " + + "${PlaceContract.COLUMN_NAME_ADDRESS} TEXT, " + + "${PlaceContract.COLUMN_NAME_TYPE} TEXT)") + } + + override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { + db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.TABLE_NAME}") + onCreate(db) + } +} \ No newline at end of file From 96926be6d7d609ba3b54afa73666376c5f9a9362 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 17:41:31 +0900 Subject: [PATCH 04/31] =?UTF-8?q?Feat:=20=EC=83=9D=EC=84=B1=20addPlace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 장소 추가 함수 --- app/src/main/java/campus/tech/kakao/map/Place.kt | 3 +++ .../java/campus/tech/kakao/map/PlaceDbHelper.kt | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/Place.kt diff --git a/app/src/main/java/campus/tech/kakao/map/Place.kt b/app/src/main/java/campus/tech/kakao/map/Place.kt new file mode 100644 index 00000000..904256a6 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/Place.kt @@ -0,0 +1,3 @@ +package campus.tech.kakao.map + +data class Place(val name: String, val address: String, val type: String) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index f9eacb1c..1f4544ae 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -1,5 +1,6 @@ package campus.tech.kakao.map +import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper @@ -8,8 +9,7 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( context, "place.db", null, 1) { override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + - "(id INTEGER PRIMARY KEY, " + - "${PlaceContract.COLUMN_NAME_NAME} TEXT, " + + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + "${PlaceContract.COLUMN_NAME_ADDRESS} TEXT, " + "${PlaceContract.COLUMN_NAME_TYPE} TEXT)") } @@ -18,4 +18,14 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.TABLE_NAME}") onCreate(db) } + + fun addPlace(place: Place) { + val db = writableDatabase + val values = ContentValues() + values.put(PlaceContract.COLUMN_NAME_NAME, place.name) + values.put(PlaceContract.COLUMN_NAME_ADDRESS, place.address) + values.put(PlaceContract.COLUMN_NAME_TYPE, place.type) + db.insert(PlaceContract.TABLE_NAME, null, values) + db.close() + } } \ No newline at end of file From 6080cee2d7980f8dad1e15e422f82de5cf586c1c Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 18:07:15 +0900 Subject: [PATCH 05/31] =?UTF-8?q?Feat[PlaceDbHelper.kt]:=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20existPlace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 매개 변수로 받은 Place가 존재하는지 확인 --- .../campus/tech/kakao/map/PlaceDbHelper.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 1f4544ae..0aec7456 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -28,4 +28,23 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( db.insert(PlaceContract.TABLE_NAME, null, values) db.close() } + + fun existPlace(place: Place, db: SQLiteDatabase): Boolean{ + val selection = "${PlaceContract.COLUMN_NAME_NAME} like ? AND " + + "${PlaceContract.COLUMN_NAME_ADDRESS} like ? AND " + + "${PlaceContract.COLUMN_NAME_TYPE} like ?" + val cursor = db.query( + PlaceContract.TABLE_NAME, + arrayOf(PlaceContract.COLUMN_NAME_NAME), + selection, + arrayOf(place.name, place.address, place.type), + null, + null, + "${PlaceContract.COLUMN_NAME_NAME} DESC" + ) + + val result = cursor.moveToFirst() + cursor.close() + return if (result) true else false + } } \ No newline at end of file From 9a75a01cdfe6e100de70eefd546f74a381ff2c48 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 18:20:51 +0900 Subject: [PATCH 06/31] =?UTF-8?q?Feat[PlaceDbHelper.kt]:=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20addPlace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 추가할 장소가 존재하지 않으면 추가 --- .../java/campus/tech/kakao/map/PlaceDbHelper.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 0aec7456..13ca94c8 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -21,12 +21,14 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( fun addPlace(place: Place) { val db = writableDatabase - val values = ContentValues() - values.put(PlaceContract.COLUMN_NAME_NAME, place.name) - values.put(PlaceContract.COLUMN_NAME_ADDRESS, place.address) - values.put(PlaceContract.COLUMN_NAME_TYPE, place.type) - db.insert(PlaceContract.TABLE_NAME, null, values) - db.close() + if (!existPlace(place, db)){ + val values = ContentValues() + values.put(PlaceContract.COLUMN_NAME_NAME, place.name) + values.put(PlaceContract.COLUMN_NAME_ADDRESS, place.address) + values.put(PlaceContract.COLUMN_NAME_TYPE, place.type) + db.insert(PlaceContract.TABLE_NAME, null, values) + db.close() + } } fun existPlace(place: Place, db: SQLiteDatabase): Boolean{ From 8ab4b192cf12c39c0c235140ee5fc833cc40a7ac Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 18:36:29 +0900 Subject: [PATCH 07/31] =?UTF-8?q?Feat[PlaceDbHelper.kt]:=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20searchPlaceName?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이름을 검색해서, 검색어를 포함하는 이름을 가진 장소 데이터를 리턴하는 함수 --- .../campus/tech/kakao/map/PlaceDbHelper.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 13ca94c8..69d362ee 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -49,4 +49,34 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( cursor.close() return if (result) true else false } + + fun searchPlaceName(name: String): List{ + val results = mutableListOf() + var searchResult = "%${name}%" + val cursor = readableDatabase.query( + PlaceContract.TABLE_NAME, + arrayOf(PlaceContract.COLUMN_NAME_NAME, + PlaceContract.COLUMN_NAME_ADDRESS, + PlaceContract.COLUMN_NAME_TYPE), + "${PlaceContract.COLUMN_NAME_NAME} like ?", + arrayOf(searchResult), + null, + null, + "${PlaceContract.COLUMN_NAME_NAME} ASC" + ) + + while (cursor.moveToNext()) { + val name = cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_NAME) + ) + val address = cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_ADDRESS) + ) + val type = cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_TYPE)) + results.add(Place(name, address, type)) + } + cursor.close() + return results + } } \ No newline at end of file From a2f41faed7aefd8da9e9ec9b389c6d1eb4a59e14 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 19:11:37 +0900 Subject: [PATCH 08/31] =?UTF-8?q?Feat[PlaceDbHelper.kt]:=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20existData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 데이터베이스에 데이터가 있는지 확인하는 함수 --- .../campus/tech/kakao/map/PlaceDbHelper.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 69d362ee..8f3df3b1 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -6,7 +6,7 @@ import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper class PlaceDbHelper(context: Context):SQLiteOpenHelper( - context, "place.db", null, 1) { + context, "place.db", null, 2) { override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + @@ -31,6 +31,22 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( } } + fun existData(): Boolean{ + val db = readableDatabase + val cursor = db.query( + PlaceContract.TABLE_NAME, + arrayOf(PlaceContract.COLUMN_NAME_NAME), + null, + null, + null, + null, + null + ) + val result = cursor.moveToFirst() + cursor.close() + return if (result) true else false + } + fun existPlace(place: Place, db: SQLiteDatabase): Boolean{ val selection = "${PlaceContract.COLUMN_NAME_NAME} like ? AND " + "${PlaceContract.COLUMN_NAME_ADDRESS} like ? AND " + From 175ca91c022825e45fc2056ad87fcbf35493b814 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 19:21:08 +0900 Subject: [PATCH 09/31] =?UTF-8?q?Feat[]:=20=EC=B6=94=EA=B0=80=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=EC=97=90=20=EC=82=AC=EC=9A=A9=EB=90=A0=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../campus/tech/kakao/map/MainActivity.kt | 38 +++++-------------- .../campus/tech/kakao/map/MainViewModel.kt | 21 ++++++++++ .../campus/tech/kakao/map/PlaceDbHelper.kt | 2 +- 3 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/MainViewModel.kt diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index c17e4001..5d399caf 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -10,34 +10,16 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - val db = PlaceDbHelper(this) - val writableDatabase = db.writableDatabase - val values = ContentValues() - values.put(PlaceContract.COLUMN_NAME_NAME, "카페1") - values.put(PlaceContract.COLUMN_NAME_ADDRESS, "서울시 강남구") - - writableDatabase.insert(PlaceContract.TABLE_NAME, null, values) - - val readableDatabase = db.readableDatabase - var searchResult = "%카페%" - val cursor = readableDatabase.query( - PlaceContract.TABLE_NAME, - arrayOf(PlaceContract.COLUMN_NAME_NAME), - "${PlaceContract.COLUMN_NAME_NAME} like ?", - arrayOf(searchResult), - null, - null, - "${PlaceContract.COLUMN_NAME_NAME} DESC" - ) - - val result = mutableListOf() - while (cursor.moveToNext()) { - result.add( - cursor.getString( - cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_NAME) - ) - ) + val dbHelper = PlaceDbHelper(applicationContext) + val db = dbHelper.writableDatabase +// dbHelper.onUpgrade(db, 1, 2) + val mainViewModel = MainViewModel(application) + mainViewModel.insertInitData() + var places = mutableListOf() + places = dbHelper.searchPlaceName("") + places.forEach { + Log.d("testt", "onCreate: ${it.name}") } - cursor.close() + } } diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt new file mode 100644 index 00000000..242419ed --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -0,0 +1,21 @@ +package campus.tech.kakao.map + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class MainViewModel(application: Application): AndroidViewModel(application) { + private var placeList = MutableLiveData>() + private val dbHelper = PlaceDbHelper(application) + + fun insertInitData(){ + if (!dbHelper.existData()){ + for(i in 1..10){ + dbHelper.addPlace(Place("카페 $i", "남양주 $i", "카페")) + dbHelper.addPlace(Place("약국 $i", "남양주 $i", "약국")) + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 8f3df3b1..4923ba61 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -66,7 +66,7 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( return if (result) true else false } - fun searchPlaceName(name: String): List{ + fun searchPlaceName(name: String): MutableList{ val results = mutableListOf() var searchResult = "%${name}%" val cursor = readableDatabase.query( From c3c7e22e1a32a8de057efbb2cea532ac8be6a6ed Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 21:18:16 +0900 Subject: [PATCH 10/31] =?UTF-8?q?Docs[README.md]:=20=EC=B6=94=EA=B0=80=202?= =?UTF-8?q?=EB=8B=A8=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 585b9b2f..15b23bce 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,20 @@ - 검색 데이터는 저장은 SQLite를 사용한다. - 가능한 MVVM 아키텍처 패턴을 적용하도록 한다. - 코드 컨벤션을 준수하며 프로그래밍한다. + +# 2단계 + +## 기능 요구 사항 +- 검색어를 입력하면 검색 결과 목록이 표시된다. +- 검색 결과 목록은 세로 스크롤이 된다. +- 입력한 검색어는 X를 눌러서 삭제할 수 있다. +- 검색 결과 목록에서 하나의 항목을 선택할 수 있다. +- 선택된 항목은 검색어 저장 목록에 추가된다. + - 목록에 있는 검색 결과를 다시 선택하면 기존 저장 목록에서 지워지고 가장 끝에 다시 추가된다. +- 저장된 검색어 목록은 가로 스크롤이 된다. +- 저장된 검색어는 X를 눌러서 삭제할 수 있다. +- 저장된 검색어는 앱을 재실행하여도 유지된다. + +## 프로그래밍 요구 사항 +- 검색 결과 목록은 리사이클러뷰를 사용한다. +- 가능한 MVVM 아키텍처 패턴을 적용하도록 한다. From 76521a082e2e0c12ba9428c56b1163a91b44db0f Mon Sep 17 00:00:00 2001 From: jmc98 Date: Fri, 5 Jul 2024 21:30:34 +0900 Subject: [PATCH 11/31] =?UTF-8?q?Docs[README.md]:=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=9C=EC=B2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 15b23bce..caa1593b 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,7 @@ ## 프로그래밍 요구 사항 - 검색 결과 목록은 리사이클러뷰를 사용한다. - 가능한 MVVM 아키텍처 패턴을 적용하도록 한다. + +## 이미지 출처 +- 위치 마커 아이콘 제작자: bsd - Flaticon +- 문자 x 아이콘 제작자: Freepik - Flaticon From c4505c02de890dab27f89fb8155eec1abe8569ff Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 17:13:04 +0900 Subject: [PATCH 12/31] =?UTF-8?q?Feat[]:=20=EC=B6=94=EA=B0=80=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B2=B0=EA=B3=BC=20=EB=AA=A9=EB=A1=9D=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 검색어를 입력하면 검색 결과 목록이 표시되고, 목록은 세로 스크롤이 됨 --- app/build.gradle.kts | 4 +- .../campus/tech/kakao/map/MainActivity.kt | 67 +++++++++++++++--- .../campus/tech/kakao/map/MainViewModel.kt | 8 ++- .../campus/tech/kakao/map/PlaceDbHelper.kt | 10 +-- .../tech/kakao/map/RecyclerViewAdapter.kt | 45 ++++++++++++ app/src/main/res/drawable/marker.png | Bin 0 -> 16096 bytes app/src/main/res/layout/activity_main.xml | 10 +++ app/src/main/res/layout/place_item.xml | 47 ++++++++++++ 8 files changed, 175 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt create mode 100644 app/src/main/res/drawable/marker.png create mode 100644 app/src/main/res/layout/place_item.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9932d6bb..f79cc952 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -40,7 +40,9 @@ android { } dependencies { - + val lifecycle_version = "2.8.3" + implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version") + implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version") implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.11.0") diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 5d399caf..77c6d60e 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -2,24 +2,71 @@ package campus.tech.kakao.map import android.content.ContentValues import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.util.Log +import android.view.View +import android.widget.EditText +import android.widget.TextView import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { + + private lateinit var model: MainViewModel + private lateinit var search:EditText + private lateinit var clear: TextView + private lateinit var noResult: TextView + private lateinit var searchResult: RecyclerView + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + UISetting() + searchResult.layoutManager = LinearLayoutManager(this) + search.addTextChangedListener(object : TextWatcher{ + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + val query = s.toString() + if (query.isEmpty()){ + noResult.visibility = View.VISIBLE + searchResult.visibility = View.GONE + }else{ + noResult.visibility = View.GONE + searchResult.visibility = View.VISIBLE + model.search(query) + } + } - val dbHelper = PlaceDbHelper(applicationContext) - val db = dbHelper.writableDatabase -// dbHelper.onUpgrade(db, 1, 2) - val mainViewModel = MainViewModel(application) - mainViewModel.insertInitData() - var places = mutableListOf() - places = dbHelper.searchPlaceName("") - places.forEach { - Log.d("testt", "onCreate: ${it.name}") - } + override fun afterTextChanged(s: Editable?) { + } + }) + model = ViewModelProvider(this).get(MainViewModel::class.java) + model.placeList.observe(this, Observer { + if (it.isNullOrEmpty()){ + noResult.visibility = View.VISIBLE + searchResult.visibility = View.GONE + }else{ + noResult.visibility = View.GONE + searchResult.visibility = View.VISIBLE + searchResult.adapter = RecyclerViewAdapter(it) + } + }) + + } + + fun UISetting(){ + search = findViewById(R.id.search) + clear = findViewById(R.id.search_clear) + noResult = findViewById(R.id.no_search_result) + searchResult = findViewById(R.id.search_result_recycler_view) } + } diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index 242419ed..5027e7f5 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -2,12 +2,14 @@ package campus.tech.kakao.map import android.app.Application import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class MainViewModel(application: Application): AndroidViewModel(application) { - private var placeList = MutableLiveData>() private val dbHelper = PlaceDbHelper(application) + val placeList: LiveData> get() = dbHelper._place + fun insertInitData(){ if (!dbHelper.existData()){ @@ -18,4 +20,8 @@ class MainViewModel(application: Application): AndroidViewModel(application) { } } + + fun search(query: String) { + dbHelper.searchPlaceName(query) + } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 4923ba61..9e13e17d 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -4,9 +4,11 @@ import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper +import androidx.lifecycle.MutableLiveData class PlaceDbHelper(context: Context):SQLiteOpenHelper( context, "place.db", null, 2) { + val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + @@ -66,8 +68,8 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( return if (result) true else false } - fun searchPlaceName(name: String): MutableList{ - val results = mutableListOf() + fun searchPlaceName(name: String){ + val resultList = mutableListOf() var searchResult = "%${name}%" val cursor = readableDatabase.query( PlaceContract.TABLE_NAME, @@ -90,9 +92,9 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( ) val type = cursor.getString( cursor.getColumnIndexOrThrow(PlaceContract.COLUMN_NAME_TYPE)) - results.add(Place(name, address, type)) + resultList.add(Place(name, address, type)) } cursor.close() - return results + _place.value = resultList } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt b/app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt new file mode 100644 index 00000000..3d2ecafe --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt @@ -0,0 +1,45 @@ +package campus.tech.kakao.map + +import android.content.Intent +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.RecyclerView + +class RecyclerViewAdapter( + val placeList: MutableList +): RecyclerView.Adapter() { + inner class ViewHolder( + itemView: View + ): RecyclerView.ViewHolder(itemView) { + val name:TextView = itemView.findViewById(R.id.name) + val address:TextView = itemView.findViewById(R.id.address) + val type:TextView = itemView.findViewById(R.id.type) + init { + itemView.setOnClickListener { + val position:Int = bindingAdapterPosition + val place:Place = placeList[position] + Log.d("testt", "Clicked on ${place.name}") + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.place_item, parent, false)) + } + + override fun getItemCount(): Int { + return placeList.size + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.name.text = placeList[position].name + holder.address.text = placeList[position].address + holder.type.text = placeList[position].type + } +} + + diff --git a/app/src/main/res/drawable/marker.png b/app/src/main/res/drawable/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..5519a07d6f3017d94125926c79513fc2c4632244 GIT binary patch literal 16096 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 rCl-TeB~4V&H|CvGpD>=h_5BmS%GxJw|840(;Li + + diff --git a/app/src/main/res/layout/place_item.xml b/app/src/main/res/layout/place_item.xml new file mode 100644 index 00000000..fa5da065 --- /dev/null +++ b/app/src/main/res/layout/place_item.xml @@ -0,0 +1,47 @@ + + + + + + + + + + \ No newline at end of file From 217b4d8e2354cb9d5d5430c4a3fde6af67d32e99 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 17:15:23 +0900 Subject: [PATCH 13/31] =?UTF-8?q?Feat[MainActivity.kt]:=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20X=EB=A5=BC=20=EB=88=8C=EB=9F=AC=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EA=B2=80=EC=83=89=EC=96=B4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/MainActivity.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 77c6d60e..a6044939 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -67,6 +67,9 @@ class MainActivity : AppCompatActivity() { clear = findViewById(R.id.search_clear) noResult = findViewById(R.id.no_search_result) searchResult = findViewById(R.id.search_result_recycler_view) + clear.setOnClickListener { + search.setText("") + } } } From 119090f505b9b22c0dfb2ece4bc87d8ba05231c5 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 18:10:49 +0900 Subject: [PATCH 14/31] =?UTF-8?q?Fix[PlaceDbHelper.kt]:=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20existPlace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 장소 확인을 like 대신 = 으로 변경 --- app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 9e13e17d..368a1923 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -50,9 +50,9 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( } fun existPlace(place: Place, db: SQLiteDatabase): Boolean{ - val selection = "${PlaceContract.COLUMN_NAME_NAME} like ? AND " + - "${PlaceContract.COLUMN_NAME_ADDRESS} like ? AND " + - "${PlaceContract.COLUMN_NAME_TYPE} like ?" + val selection = "${PlaceContract.COLUMN_NAME_NAME} = ? AND " + + "${PlaceContract.COLUMN_NAME_ADDRESS} = ? AND " + + "${PlaceContract.COLUMN_NAME_TYPE} = ?" val cursor = db.query( PlaceContract.TABLE_NAME, arrayOf(PlaceContract.COLUMN_NAME_NAME), From 5aaa892375a3f41f3e0868f8609f119ffa623a52 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 18:19:37 +0900 Subject: [PATCH 15/31] =?UTF-8?q?Refactor[]:=20Place=20DB=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EC=9D=84=20=EC=83=81=EC=88=98=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/PlaceContract.kt | 1 + app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt index e8d1aff1..1041d382 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt @@ -3,6 +3,7 @@ package campus.tech.kakao.map import android.provider.BaseColumns object PlaceContract:BaseColumns { + const val DB_NAME = "place.db" const val TABLE_NAME = "place" const val COLUMN_NAME_NAME = "name" const val COLUMN_NAME_ADDRESS = "address" diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 368a1923..2c4efca2 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -7,7 +7,7 @@ import android.database.sqlite.SQLiteOpenHelper import androidx.lifecycle.MutableLiveData class PlaceDbHelper(context: Context):SQLiteOpenHelper( - context, "place.db", null, 2) { + context, PlaceContract.DB_NAME, null, 2) { val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + From 790679a28f8a70c62641a582afe502a6afe5707a Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 19:41:23 +0900 Subject: [PATCH 16/31] =?UTF-8?q?Rename[PlaceAdapter]:=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=9D=B4=EB=A6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../map/{RecyclerViewAdapter.kt => PlaceAdapter.kt} | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) rename app/src/main/java/campus/tech/kakao/map/{RecyclerViewAdapter.kt => PlaceAdapter.kt} (82%) diff --git a/app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt similarity index 82% rename from app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt rename to app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt index 3d2ecafe..e6e68fd4 100644 --- a/app/src/main/java/campus/tech/kakao/map/RecyclerViewAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt @@ -1,17 +1,16 @@ package campus.tech.kakao.map -import android.content.Intent import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import androidx.lifecycle.LiveData import androidx.recyclerview.widget.RecyclerView -class RecyclerViewAdapter( - val placeList: MutableList -): RecyclerView.Adapter() { +class PlaceAdapter( + val placeList: MutableList, + val viewModel: MainViewModel +): RecyclerView.Adapter() { inner class ViewHolder( itemView: View ): RecyclerView.ViewHolder(itemView) { @@ -22,7 +21,7 @@ class RecyclerViewAdapter( itemView.setOnClickListener { val position:Int = bindingAdapterPosition val place:Place = placeList[position] - Log.d("testt", "Clicked on ${place.name}") + viewModel.addWord(place) } } } From c2baa69a95d550bfe2aee6a6729c3985e2b94e3c Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 19:42:10 +0900 Subject: [PATCH 17/31] =?UTF-8?q?Refactor[PlaceDbHelper]:=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20existData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit result를 리턴하도록 변경 --- app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 2c4efca2..90a2dfbf 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -46,7 +46,7 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( ) val result = cursor.moveToFirst() cursor.close() - return if (result) true else false + return result } fun existPlace(place: Place, db: SQLiteDatabase): Boolean{ From 78eacb1d46eb949ca32791bd73d83ef39c89ee97 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 20:00:20 +0900 Subject: [PATCH 18/31] =?UTF-8?q?Feat[]:=20=EC=B6=94=EA=B0=80=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B2=B0=EA=B3=BC=20=EB=AA=A9=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 검색 결과 목록에서 하나의 항목을 선택하면, 검색어 저장 목록에 추가가 되고 가로 스크롤이 됨. --- .../campus/tech/kakao/map/MainActivity.kt | 20 +++- .../campus/tech/kakao/map/MainViewModel.kt | 26 ++++- .../java/campus/tech/kakao/map/SearchWord.kt | 3 + .../tech/kakao/map/SearchWordContract.kt | 10 ++ .../tech/kakao/map/SearchWordDbHelper.kt | 110 ++++++++++++++++++ .../java/campus/tech/kakao/map/WordAdapter.kt | 40 +++++++ app/src/main/res/layout/activity_main.xml | 9 +- app/src/main/res/layout/word_item.xml | 23 ++++ 8 files changed, 231 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/SearchWord.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/WordAdapter.kt create mode 100644 app/src/main/res/layout/word_item.xml diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index a6044939..5718004e 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -1,6 +1,5 @@ package campus.tech.kakao.map -import android.content.ContentValues import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -21,12 +20,14 @@ class MainActivity : AppCompatActivity() { private lateinit var clear: TextView private lateinit var noResult: TextView private lateinit var searchResult: RecyclerView + private lateinit var searchWordResult: RecyclerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) UISetting() searchResult.layoutManager = LinearLayoutManager(this) + searchWordResult.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) search.addTextChangedListener(object : TextWatcher{ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { @@ -34,7 +35,7 @@ class MainActivity : AppCompatActivity() { override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { val query = s.toString() - if (query.isEmpty()){ + if (query.isNullOrEmpty()){ noResult.visibility = View.VISIBLE searchResult.visibility = View.GONE }else{ @@ -56,7 +57,19 @@ class MainActivity : AppCompatActivity() { }else{ noResult.visibility = View.GONE searchResult.visibility = View.VISIBLE - searchResult.adapter = RecyclerViewAdapter(it) + searchResult.adapter = PlaceAdapter(it, model) + } + }) + + model.wordList.observe(this, Observer { + if (it.isNullOrEmpty()){ + searchWordResult.visibility = View.GONE + Log.d("testt", "null") + } + else{ + searchWordResult.visibility = View.VISIBLE + searchWordResult.adapter = WordAdapter(it, model) + Log.d("testt", it[0].name) } }) @@ -67,6 +80,7 @@ class MainActivity : AppCompatActivity() { clear = findViewById(R.id.search_clear) noResult = findViewById(R.id.no_search_result) searchResult = findViewById(R.id.search_result_recycler_view) + searchWordResult = findViewById(R.id.search_word_recycler_view) clear.setOnClickListener { search.setText("") } diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index 5027e7f5..df1d6204 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -1,27 +1,41 @@ package campus.tech.kakao.map import android.app.Application +import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class MainViewModel(application: Application): AndroidViewModel(application) { - private val dbHelper = PlaceDbHelper(application) - val placeList: LiveData> get() = dbHelper._place + private val placeDbHelper = PlaceDbHelper(application) + val placeList: LiveData> get() = placeDbHelper._place + private val wordDbHelper = SearchWordDbHelper(application) + val wordList: LiveData> get() = wordDbHelper._searchWords fun insertInitData(){ - if (!dbHelper.existData()){ + if (!placeDbHelper.existData()){ for(i in 1..10){ - dbHelper.addPlace(Place("카페 $i", "남양주 $i", "카페")) - dbHelper.addPlace(Place("약국 $i", "남양주 $i", "약국")) + placeDbHelper.addPlace(Place("카페 $i", "남양주 $i", "카페")) + placeDbHelper.addPlace(Place("약국 $i", "남양주 $i", "약국")) } } } fun search(query: String) { - dbHelper.searchPlaceName(query) + placeDbHelper.searchPlaceName(query) + } + + fun addWord(place: Place){ + wordDbHelper.addWord(WordfromPlace(place)) + } + + fun WordfromPlace(place: Place):SearchWord{ + return SearchWord(place.name, place.address, place.type) + } + fun deleteWord(word: SearchWord){ + wordDbHelper.deleteWord(word) } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWord.kt b/app/src/main/java/campus/tech/kakao/map/SearchWord.kt new file mode 100644 index 00000000..980b1625 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/SearchWord.kt @@ -0,0 +1,3 @@ +package campus.tech.kakao.map + +data class SearchWord(val name: String, val address: String, val type: String) diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt new file mode 100644 index 00000000..a5e58b99 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt @@ -0,0 +1,10 @@ +package campus.tech.kakao.map + +object SearchWordContract { + const val DB_NAME = "search_word.db" + const val TABLE_NAME = "SearchWord" + const val COLUMN_NAME_NAME = "name" + const val COLUMN_NAME_ADDRESS = "address" + const val COLUMN_NAME_TYPE = "type" + +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt new file mode 100644 index 00000000..36ffd9ba --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -0,0 +1,110 @@ +package campus.tech.kakao.map + +import android.content.ContentValues +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import android.util.Log +import androidx.lifecycle.MutableLiveData + +class SearchWordDbHelper(context: Context): SQLiteOpenHelper( + context, SearchWordContract.DB_NAME, null, 1) { + val _searchWords = MutableLiveData>() + val searchSameSelection = "${SearchWordContract.COLUMN_NAME_NAME} = ? AND " + + "${SearchWordContract.COLUMN_NAME_ADDRESS} = ? AND " + + "${SearchWordContract.COLUMN_NAME_TYPE} = ?" + override fun onCreate(db: SQLiteDatabase?) { + db?.execSQL( + "CREATE TABLE ${SearchWordContract.TABLE_NAME} " + + "(${SearchWordContract.COLUMN_NAME_NAME} TEXT, " + + "${SearchWordContract.COLUMN_NAME_ADDRESS} TEXT, " + + "${SearchWordContract.COLUMN_NAME_TYPE} TEXT)" + ) + } + + override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { + db?.execSQL("DROP TABLE IF EXISTS ${SearchWordContract.TABLE_NAME}") + onCreate(db) + } + + fun addWord(word: SearchWord) { + val db = writableDatabase + if (existWord(word, db)){ + deleteWord(word) + } + val values = ContentValues() + values.put(SearchWordContract.COLUMN_NAME_NAME, word.name) + values.put(SearchWordContract.COLUMN_NAME_ADDRESS, word.address) + values.put(SearchWordContract.COLUMN_NAME_TYPE, word.type) + db.insert(SearchWordContract.TABLE_NAME, null, values) + db.close() + updateSearchWords() + } + + fun existData(): Boolean{ + val db = readableDatabase + val cursor = db.query( + SearchWordContract.TABLE_NAME, + arrayOf(SearchWordContract.COLUMN_NAME_NAME), + null, + null, + null, + null, + null + ) + val result = cursor.moveToFirst() + cursor.close() + return result + } + + fun existWord(word: SearchWord, db: SQLiteDatabase): Boolean{ + val selection = searchSameSelection + val cursor = db.query( + SearchWordContract.TABLE_NAME, + arrayOf(SearchWordContract.COLUMN_NAME_NAME), + selection, + arrayOf(word.name, word.address, word.type), + null, + null, + "${SearchWordContract.COLUMN_NAME_NAME} DESC" + ) + + val result = cursor.moveToFirst() + cursor.close() + return if (result) true else false + } + + fun deleteWord(word: SearchWord){ + val db = writableDatabase + val selection = searchSameSelection + val selectionArgs = arrayOf(word.name, word.address, word.type) + db.delete(SearchWordContract.TABLE_NAME, selection, selectionArgs) + } + + fun updateSearchWords(){ + val db = readableDatabase + var resultList = mutableListOf() + val cursor = db.query( + SearchWordContract.TABLE_NAME, + arrayOf(SearchWordContract.COLUMN_NAME_NAME, SearchWordContract.COLUMN_NAME_ADDRESS, SearchWordContract.COLUMN_NAME_TYPE), + null, + null, + null, + null, + null + ) + while (cursor.moveToNext()) { + val name = cursor.getString( + cursor.getColumnIndexOrThrow(SearchWordContract.COLUMN_NAME_NAME) + ) + val address = cursor.getString( + cursor.getColumnIndexOrThrow(SearchWordContract.COLUMN_NAME_ADDRESS) + ) + val type = cursor.getString( + cursor.getColumnIndexOrThrow(SearchWordContract.COLUMN_NAME_TYPE)) + resultList.add(SearchWord(name, address, type)) + } + cursor.close() + _searchWords.value = resultList + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt new file mode 100644 index 00000000..42b6f5b1 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt @@ -0,0 +1,40 @@ +package campus.tech.kakao.map + +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class WordAdapter( + val wordList: MutableList, + val viewModel: MainViewModel +): RecyclerView.Adapter() { + inner class ViewHolder( + itemView: View + ): RecyclerView.ViewHolder(itemView) { + val searchWord: TextView = itemView.findViewById(R.id.search_word) + val delete: ImageView = itemView.findViewById(R.id.x) + init { + delete.setOnClickListener { + val position:Int = bindingAdapterPosition + val word:SearchWord = wordList[position] + viewModel.deleteWord(word) + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.word_item, parent, false)) + } + + override fun getItemCount(): Int { + return wordList.size + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.searchWord.text = wordList[position].name + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3a5c573c..f1ac7119 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -41,6 +41,13 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + app:layout_constraintTop_toBottomOf="@+id/search_word_recycler_view" /> diff --git a/app/src/main/res/layout/word_item.xml b/app/src/main/res/layout/word_item.xml new file mode 100644 index 00000000..a14c1c28 --- /dev/null +++ b/app/src/main/res/layout/word_item.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file From 568b0f90a35d1a870dcb5e26e96de26966b6f551 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 20:21:10 +0900 Subject: [PATCH 19/31] =?UTF-8?q?Feat[SearchWordDbHelper]:=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EA=B2=80=EC=83=89=EC=96=B4=20x=20=EB=88=8C?= =?UTF-8?q?=EB=9F=AC=EC=84=9C=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index 36ffd9ba..a4b39376 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -79,6 +79,7 @@ class SearchWordDbHelper(context: Context): SQLiteOpenHelper( val selection = searchSameSelection val selectionArgs = arrayOf(word.name, word.address, word.type) db.delete(SearchWordContract.TABLE_NAME, selection, selectionArgs) + updateSearchWords() } fun updateSearchWords(){ From 204ffcb5840ca29d2ccf10e246a9c49f4f742e7d Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sat, 6 Jul 2024 20:23:53 +0900 Subject: [PATCH 20/31] =?UTF-8?q?Feat[]:=20=EC=B6=94=EA=B0=80=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=EC=96=B4=20=EC=9E=AC=EC=8B=A4=ED=96=89=20=EC=9C=A0?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 저장된 검색어는 앱을 재실행하여도 유지된다. --- app/src/main/java/campus/tech/kakao/map/MainActivity.kt | 2 +- app/src/main/java/campus/tech/kakao/map/MainViewModel.kt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 5718004e..a61614fd 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -60,7 +60,7 @@ class MainActivity : AppCompatActivity() { searchResult.adapter = PlaceAdapter(it, model) } }) - + model.loadWord() model.wordList.observe(this, Observer { if (it.isNullOrEmpty()){ searchWordResult.visibility = View.GONE diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index df1d6204..08fc36d7 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -38,4 +38,8 @@ class MainViewModel(application: Application): AndroidViewModel(application) { fun deleteWord(word: SearchWord){ wordDbHelper.deleteWord(word) } + + fun loadWord(){ + wordDbHelper.updateSearchWords() + } } \ No newline at end of file From 08a7a27fe5f5d2d555f1aa04035c3c93e2795bac Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 22:23:22 +0900 Subject: [PATCH 21/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=EC=96=B4=20=EA=B2=80=EC=83=89=20=EC=9D=B8?= =?UTF-8?q?=EC=8B=9D=20=EB=B0=A9=EB=B2=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit addTextChangedListener 대신 doOnTextChanged를 사용하였다. --- .../campus/tech/kakao/map/MainActivity.kt | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index a61614fd..2fc455ae 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -8,6 +8,7 @@ import android.view.View import android.widget.EditText import android.widget.TextView import androidx.appcompat.app.AppCompatActivity +import androidx.core.widget.doOnTextChanged import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager @@ -28,27 +29,18 @@ class MainActivity : AppCompatActivity() { UISetting() searchResult.layoutManager = LinearLayoutManager(this) searchWordResult.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) - search.addTextChangedListener(object : TextWatcher{ - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - val query = s.toString() - if (query.isNullOrEmpty()){ - noResult.visibility = View.VISIBLE - searchResult.visibility = View.GONE - }else{ - noResult.visibility = View.GONE - searchResult.visibility = View.VISIBLE - model.search(query) - } - } - - override fun afterTextChanged(s: Editable?) { + + search.doOnTextChanged { text, start, before, count -> + val query = text.toString() + if (query.isNullOrEmpty()){ + noResult.visibility = View.VISIBLE + searchResult.visibility = View.GONE + }else{ + noResult.visibility = View.GONE + searchResult.visibility = View.VISIBLE + model.search(query) } - - }) + } model = ViewModelProvider(this).get(MainViewModel::class.java) model.placeList.observe(this, Observer { if (it.isNullOrEmpty()){ From 0890b9e7b8f20e372ca84441984f2a5e19c247db Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 22:28:16 +0900 Subject: [PATCH 22/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20UI?= =?UTF-8?q?=EC=84=B8=ED=8C=85=20=ED=95=A8=EC=88=98=EB=AA=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UISetting에서 setupUI로 변경 --- app/src/main/java/campus/tech/kakao/map/MainActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 2fc455ae..ee51bdac 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -26,7 +26,7 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - UISetting() + setupUI() searchResult.layoutManager = LinearLayoutManager(this) searchWordResult.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) @@ -67,7 +67,7 @@ class MainActivity : AppCompatActivity() { } - fun UISetting(){ + fun setupUI(){ search = findViewById(R.id.search) clear = findViewById(R.id.search_clear) noResult = findViewById(R.id.no_search_result) From 2bfa7813c16ce4cbe20626e11896278071f7fd6d Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 22:30:11 +0900 Subject: [PATCH 23/31] =?UTF-8?q?Comment[MainActivity]:=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=9A=A9=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/MainActivity.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index ee51bdac..be53094d 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -56,12 +56,10 @@ class MainActivity : AppCompatActivity() { model.wordList.observe(this, Observer { if (it.isNullOrEmpty()){ searchWordResult.visibility = View.GONE - Log.d("testt", "null") } else{ searchWordResult.visibility = View.VISIBLE searchWordResult.adapter = WordAdapter(it, model) - Log.d("testt", it[0].name) } }) From b868cb33ff1facea901d0521923fb80231927757 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 22:33:29 +0900 Subject: [PATCH 24/31] =?UTF-8?q?Refactor[MainActivity]:=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20warning=20=EB=B6=80=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/MainActivity.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index be53094d..4d013fc2 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -1,9 +1,6 @@ package campus.tech.kakao.map import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.util.Log import android.view.View import android.widget.EditText import android.widget.TextView @@ -32,7 +29,7 @@ class MainActivity : AppCompatActivity() { search.doOnTextChanged { text, start, before, count -> val query = text.toString() - if (query.isNullOrEmpty()){ + if (query.isEmpty()){ noResult.visibility = View.VISIBLE searchResult.visibility = View.GONE }else{ @@ -41,7 +38,7 @@ class MainActivity : AppCompatActivity() { model.search(query) } } - model = ViewModelProvider(this).get(MainViewModel::class.java) + model = ViewModelProvider(this)[MainViewModel::class.java] model.placeList.observe(this, Observer { if (it.isNullOrEmpty()){ noResult.visibility = View.VISIBLE From 326f7118cf9e44741ce9f5e67515452f3dbd17e7 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 22:39:14 +0900 Subject: [PATCH 25/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20place?= =?UTF-8?q?=EC=99=80=20word=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=ED=83=80=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MutableList에서 List로 변경 --- app/src/main/java/campus/tech/kakao/map/MainViewModel.kt | 4 ++-- app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt | 2 +- app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 2 +- app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 2 +- app/src/main/java/campus/tech/kakao/map/WordAdapter.kt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index 08fc36d7..01a93984 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -9,10 +9,10 @@ import androidx.lifecycle.ViewModel class MainViewModel(application: Application): AndroidViewModel(application) { private val placeDbHelper = PlaceDbHelper(application) - val placeList: LiveData> get() = placeDbHelper._place + val placeList: LiveData> get() = placeDbHelper._place private val wordDbHelper = SearchWordDbHelper(application) - val wordList: LiveData> get() = wordDbHelper._searchWords + val wordList: LiveData> get() = wordDbHelper._searchWords fun insertInitData(){ if (!placeDbHelper.existData()){ diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt index e6e68fd4..5e7fb611 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt @@ -8,7 +8,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class PlaceAdapter( - val placeList: MutableList, + val placeList: List, val viewModel: MainViewModel ): RecyclerView.Adapter() { inner class ViewHolder( diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 90a2dfbf..72b7d2bc 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData class PlaceDbHelper(context: Context):SQLiteOpenHelper( context, PlaceContract.DB_NAME, null, 2) { - val _place = MutableLiveData>() + val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index a4b39376..203f4277 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -9,7 +9,7 @@ import androidx.lifecycle.MutableLiveData class SearchWordDbHelper(context: Context): SQLiteOpenHelper( context, SearchWordContract.DB_NAME, null, 1) { - val _searchWords = MutableLiveData>() + val _searchWords = MutableLiveData>() val searchSameSelection = "${SearchWordContract.COLUMN_NAME_NAME} = ? AND " + "${SearchWordContract.COLUMN_NAME_ADDRESS} = ? AND " + "${SearchWordContract.COLUMN_NAME_TYPE} = ?" diff --git a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt index 42b6f5b1..6690ed93 100644 --- a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt @@ -9,7 +9,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class WordAdapter( - val wordList: MutableList, + val wordList: List, val viewModel: MainViewModel ): RecyclerView.Adapter() { inner class ViewHolder( From 3dcef652adcbc1518c7f3868dfc1b7d268f20553 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 23:01:55 +0900 Subject: [PATCH 26/31] =?UTF-8?q?Refactor[]:=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=20=EC=97=86=EB=8A=94=20import,=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20WordfromPlace=20=ED=95=A8=EC=88=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/MainViewModel.kt | 8 +++----- app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt | 1 - app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 2 +- .../main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 3 +-- app/src/main/java/campus/tech/kakao/map/WordAdapter.kt | 1 - 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index 01a93984..320f347e 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -1,11 +1,8 @@ package campus.tech.kakao.map import android.app.Application -import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel class MainViewModel(application: Application): AndroidViewModel(application) { private val placeDbHelper = PlaceDbHelper(application) @@ -14,6 +11,7 @@ class MainViewModel(application: Application): AndroidViewModel(application) { private val wordDbHelper = SearchWordDbHelper(application) val wordList: LiveData> get() = wordDbHelper._searchWords + //초기에 데이터 삽입을 위해 1번 사용 fun insertInitData(){ if (!placeDbHelper.existData()){ for(i in 1..10){ @@ -29,10 +27,10 @@ class MainViewModel(application: Application): AndroidViewModel(application) { } fun addWord(place: Place){ - wordDbHelper.addWord(WordfromPlace(place)) + wordDbHelper.addWord(wordfromPlace(place)) } - fun WordfromPlace(place: Place):SearchWord{ + private fun wordfromPlace(place: Place):SearchWord{ return SearchWord(place.name, place.address, place.type) } fun deleteWord(word: SearchWord){ diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt index 5e7fb611..8672642d 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt @@ -1,6 +1,5 @@ package campus.tech.kakao.map -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 72b7d2bc..5a4a2dc0 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -70,7 +70,7 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( fun searchPlaceName(name: String){ val resultList = mutableListOf() - var searchResult = "%${name}%" + val searchResult = "%${name}%" val cursor = readableDatabase.query( PlaceContract.TABLE_NAME, arrayOf(PlaceContract.COLUMN_NAME_NAME, diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index 203f4277..880c602b 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -4,7 +4,6 @@ import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper -import android.util.Log import androidx.lifecycle.MutableLiveData class SearchWordDbHelper(context: Context): SQLiteOpenHelper( @@ -84,7 +83,7 @@ class SearchWordDbHelper(context: Context): SQLiteOpenHelper( fun updateSearchWords(){ val db = readableDatabase - var resultList = mutableListOf() + val resultList = mutableListOf() val cursor = db.query( SearchWordContract.TABLE_NAME, arrayOf(SearchWordContract.COLUMN_NAME_NAME, SearchWordContract.COLUMN_NAME_ADDRESS, SearchWordContract.COLUMN_NAME_TYPE), diff --git a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt index 6690ed93..8f384f1a 100644 --- a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt @@ -1,6 +1,5 @@ package campus.tech.kakao.map -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup From ac3814646fa35d9eb7a52384f7d64d7786986575 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 23:06:20 +0900 Subject: [PATCH 27/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20=5Fpla?= =?UTF-8?q?ce,=20=5FsearchWords=20=ED=83=80=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 두 변수를 private 선언하고, get 함수를 만들어 줌. --- app/src/main/java/campus/tech/kakao/map/MainViewModel.kt | 4 ++-- app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 6 +++++- .../main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt index 320f347e..fd7e3919 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainViewModel.kt @@ -6,10 +6,10 @@ import androidx.lifecycle.LiveData class MainViewModel(application: Application): AndroidViewModel(application) { private val placeDbHelper = PlaceDbHelper(application) - val placeList: LiveData> get() = placeDbHelper._place + val placeList: LiveData> get() = placeDbHelper.getPlace() private val wordDbHelper = SearchWordDbHelper(application) - val wordList: LiveData> get() = wordDbHelper._searchWords + val wordList: LiveData> get() = wordDbHelper.getSearchWords() //초기에 데이터 삽입을 위해 1번 사용 fun insertInitData(){ diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 5a4a2dc0..671f9439 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData class PlaceDbHelper(context: Context):SQLiteOpenHelper( context, PlaceContract.DB_NAME, null, 2) { - val _place = MutableLiveData>() + private val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + @@ -21,6 +21,10 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( onCreate(db) } + fun getPlace(): MutableLiveData> { + return _place + } + fun addPlace(place: Place) { val db = writableDatabase if (!existPlace(place, db)){ diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index 880c602b..707412bf 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData class SearchWordDbHelper(context: Context): SQLiteOpenHelper( context, SearchWordContract.DB_NAME, null, 1) { - val _searchWords = MutableLiveData>() + private val _searchWords = MutableLiveData>() val searchSameSelection = "${SearchWordContract.COLUMN_NAME_NAME} = ? AND " + "${SearchWordContract.COLUMN_NAME_ADDRESS} = ? AND " + "${SearchWordContract.COLUMN_NAME_TYPE} = ?" @@ -26,6 +26,10 @@ class SearchWordDbHelper(context: Context): SQLiteOpenHelper( onCreate(db) } + fun getSearchWords(): MutableLiveData> { + return _searchWords + } + fun addWord(word: SearchWord) { val db = writableDatabase if (existWord(word, db)){ From 8d5bdd763bfa47bfd3332f4d32b8d442d16e7f45 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 23:10:01 +0900 Subject: [PATCH 28/31] =?UTF-8?q?Refactor[]:=20=EC=B6=94=EA=B0=80=20DB=20V?= =?UTF-8?q?ersion=20=EC=83=81=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/campus/tech/kakao/map/PlaceContract.kt | 1 + app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 3 ++- app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt | 1 + app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt index 1041d382..44c0cd4d 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceContract.kt @@ -4,6 +4,7 @@ import android.provider.BaseColumns object PlaceContract:BaseColumns { const val DB_NAME = "place.db" + const val DB_VERSION = 2 const val TABLE_NAME = "place" const val COLUMN_NAME_NAME = "name" const val COLUMN_NAME_ADDRESS = "address" diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index 671f9439..f8debd73 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -5,9 +5,10 @@ import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import androidx.lifecycle.MutableLiveData +import campus.tech.kakao.map.PlaceContract.DB_VERSION class PlaceDbHelper(context: Context):SQLiteOpenHelper( - context, PlaceContract.DB_NAME, null, 2) { + context, PlaceContract.DB_NAME, null, DB_VERSION) { private val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt index a5e58b99..9e28ec13 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordContract.kt @@ -2,6 +2,7 @@ package campus.tech.kakao.map object SearchWordContract { const val DB_NAME = "search_word.db" + const val DB_VERSION = 1 const val TABLE_NAME = "SearchWord" const val COLUMN_NAME_NAME = "name" const val COLUMN_NAME_ADDRESS = "address" diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index 707412bf..0d9e0e6a 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -5,9 +5,10 @@ import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import androidx.lifecycle.MutableLiveData +import campus.tech.kakao.map.SearchWordContract.DB_VERSION class SearchWordDbHelper(context: Context): SQLiteOpenHelper( - context, SearchWordContract.DB_NAME, null, 1) { + context, SearchWordContract.DB_NAME, null, DB_VERSION) { private val _searchWords = MutableLiveData>() val searchSameSelection = "${SearchWordContract.COLUMN_NAME_NAME} = ? AND " + "${SearchWordContract.COLUMN_NAME_ADDRESS} = ? AND " + From 083eeb6e26a454f2e56a95c2ce6a0035fc2962b1 Mon Sep 17 00:00:00 2001 From: jmc98 Date: Sun, 7 Jul 2024 23:13:41 +0900 Subject: [PATCH 29/31] =?UTF-8?q?Refactor[]:=20=EC=B6=94=EA=B0=80=20create?= =?UTF-8?q?Table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit onCreate의 테이블 생성 sql 부분을 따로 함수로 분리. --- app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt | 5 ++++- .../main/java/campus/tech/kakao/map/SearchWordDbHelper.kt | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt index f8debd73..8c19c4e6 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceDbHelper.kt @@ -11,6 +11,9 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( context, PlaceContract.DB_NAME, null, DB_VERSION) { private val _place = MutableLiveData>() override fun onCreate(db: SQLiteDatabase?) { + createTable(db) + } + private fun createTable(db: SQLiteDatabase?) { db?.execSQL("CREATE TABLE ${PlaceContract.TABLE_NAME} " + "(${PlaceContract.COLUMN_NAME_NAME} TEXT, " + "${PlaceContract.COLUMN_NAME_ADDRESS} TEXT, " + @@ -19,7 +22,7 @@ class PlaceDbHelper(context: Context):SQLiteOpenHelper( override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.TABLE_NAME}") - onCreate(db) + createTable(db) } fun getPlace(): MutableLiveData> { diff --git a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt index 0d9e0e6a..cb98b5d6 100644 --- a/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt +++ b/app/src/main/java/campus/tech/kakao/map/SearchWordDbHelper.kt @@ -14,6 +14,10 @@ class SearchWordDbHelper(context: Context): SQLiteOpenHelper( "${SearchWordContract.COLUMN_NAME_ADDRESS} = ? AND " + "${SearchWordContract.COLUMN_NAME_TYPE} = ?" override fun onCreate(db: SQLiteDatabase?) { + createTable(db) + } + + private fun createTable(db: SQLiteDatabase?) { db?.execSQL( "CREATE TABLE ${SearchWordContract.TABLE_NAME} " + "(${SearchWordContract.COLUMN_NAME_NAME} TEXT, " + @@ -24,7 +28,7 @@ class SearchWordDbHelper(context: Context): SQLiteOpenHelper( override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { db?.execSQL("DROP TABLE IF EXISTS ${SearchWordContract.TABLE_NAME}") - onCreate(db) + createTable(db) } fun getSearchWords(): MutableLiveData> { From de4f9f0c71f3b4d67c0bdbb3c9bfba07b109379b Mon Sep 17 00:00:00 2001 From: jmc98 Date: Mon, 8 Jul 2024 00:02:50 +0900 Subject: [PATCH 30/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=96=B4=EB=8C=91=ED=84=B0=20=ED=81=B4=EB=A6=AD=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=EB=84=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 어댑터들의 클릭 리스너를 메인 액티비티에서 받게끔 변경 --- .../main/java/campus/tech/kakao/map/MainActivity.kt | 11 +++++++++-- .../main/java/campus/tech/kakao/map/PlaceAdapter.kt | 4 ++-- .../main/java/campus/tech/kakao/map/WordAdapter.kt | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index 4d013fc2..b140b355 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -46,7 +46,9 @@ class MainActivity : AppCompatActivity() { }else{ noResult.visibility = View.GONE searchResult.visibility = View.VISIBLE - searchResult.adapter = PlaceAdapter(it, model) + searchResult.adapter = PlaceAdapter(it){ Place -> + model.addWord(Place) + } } }) model.loadWord() @@ -56,7 +58,11 @@ class MainActivity : AppCompatActivity() { } else{ searchWordResult.visibility = View.VISIBLE - searchWordResult.adapter = WordAdapter(it, model) + searchWordResult.adapter = WordAdapter(it) { SearchWord -> + model.deleteWord( + SearchWord + ) + } } }) @@ -73,4 +79,5 @@ class MainActivity : AppCompatActivity() { } } + } diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt index 8672642d..3c4e8908 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt @@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView class PlaceAdapter( val placeList: List, - val viewModel: MainViewModel + val onItemClicked: (Place) -> Unit ): RecyclerView.Adapter() { inner class ViewHolder( itemView: View @@ -20,7 +20,7 @@ class PlaceAdapter( itemView.setOnClickListener { val position:Int = bindingAdapterPosition val place:Place = placeList[position] - viewModel.addWord(place) + onItemClicked(place) } } } diff --git a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt index 8f384f1a..c5f61c8a 100644 --- a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt @@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView class WordAdapter( val wordList: List, - val viewModel: MainViewModel + val onItemClicked: (SearchWord) -> Unit ): RecyclerView.Adapter() { inner class ViewHolder( itemView: View @@ -18,9 +18,9 @@ class WordAdapter( val delete: ImageView = itemView.findViewById(R.id.x) init { delete.setOnClickListener { - val position:Int = bindingAdapterPosition + val position = bindingAdapterPosition val word:SearchWord = wordList[position] - viewModel.deleteWord(word) + onItemClicked(word) } } } From c0f5b5b097880ee6e0a9f3b982c56e980540c1da Mon Sep 17 00:00:00 2001 From: jmc98 Date: Mon, 8 Jul 2024 14:43:12 +0900 Subject: [PATCH 31/31] =?UTF-8?q?Refactor[]:=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=96=B4=EB=8C=91=ED=84=B0=EC=97=90=20ListAdapter=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++ .../campus/tech/kakao/map/MainActivity.kt | 10 ++++- .../campus/tech/kakao/map/PlaceAdapter.kt | 37 +++++++++++++------ .../java/campus/tech/kakao/map/WordAdapter.kt | 32 +++++++++++----- 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index caa1593b..5e33e3b7 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,14 @@ - 검색 결과 목록은 리사이클러뷰를 사용한다. - 가능한 MVVM 아키텍처 패턴을 적용하도록 한다. +# 3단계 + +## 기능 요구 사항 +- 저장된 검색어 목록은 RecyclerView로 구현하고 검색 결과는 ListView로 구현해 보세요. + +## 프로그래밍 요구 사항 +- ListView 사용 시 재사용 가능한 뷰를 최대한 재사용할 수 있도록 구현한다. + ## 이미지 출처 - 위치 마커 아이콘 제작자: bsd - Flaticon - 문자 x 아이콘 제작자: Freepik - Flaticon diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt index b140b355..cf86a821 100644 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt @@ -19,6 +19,8 @@ class MainActivity : AppCompatActivity() { private lateinit var noResult: TextView private lateinit var searchResult: RecyclerView private lateinit var searchWordResult: RecyclerView + private lateinit var placeAdapter: PlaceAdapter + private lateinit var wordAdapter: WordAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -46,9 +48,11 @@ class MainActivity : AppCompatActivity() { }else{ noResult.visibility = View.GONE searchResult.visibility = View.VISIBLE - searchResult.adapter = PlaceAdapter(it){ Place -> + placeAdapter = PlaceAdapter(){ Place -> model.addWord(Place) } + placeAdapter.submitList(it) + searchResult.adapter = placeAdapter } }) model.loadWord() @@ -58,11 +62,13 @@ class MainActivity : AppCompatActivity() { } else{ searchWordResult.visibility = View.VISIBLE - searchWordResult.adapter = WordAdapter(it) { SearchWord -> + wordAdapter = WordAdapter() { SearchWord -> model.deleteWord( SearchWord ) } + wordAdapter.submitList(it) + searchWordResult.adapter = wordAdapter } }) diff --git a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt index 3c4e8908..6be747ca 100644 --- a/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/PlaceAdapter.kt @@ -4,12 +4,30 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView class PlaceAdapter( - val placeList: List, val onItemClicked: (Place) -> Unit -): RecyclerView.Adapter() { +): ListAdapter( + object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: Place, newItem: Place): Boolean { + return (oldItem.name == newItem.name) + && (oldItem.address == newItem.address) + && (oldItem.type == newItem.type) + } + + override fun areContentsTheSame(oldItem: Place, newItem: Place): Boolean { + return oldItem == newItem + } + + } +) { + private var placeClicked = { position:Int -> + val place:Place = getItem(position) + onItemClicked(place) + } inner class ViewHolder( itemView: View ): RecyclerView.ViewHolder(itemView) { @@ -18,9 +36,7 @@ class PlaceAdapter( val type:TextView = itemView.findViewById(R.id.type) init { itemView.setOnClickListener { - val position:Int = bindingAdapterPosition - val place:Place = placeList[position] - onItemClicked(place) + placeClicked(bindingAdapterPosition) } } } @@ -29,14 +45,11 @@ class PlaceAdapter( return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.place_item, parent, false)) } - override fun getItemCount(): Int { - return placeList.size - } - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.name.text = placeList[position].name - holder.address.text = placeList[position].address - holder.type.text = placeList[position].type + val place:Place = getItem(position) + holder.name.text = place.name + holder.address.text = place.address + holder.type.text = place.type } } diff --git a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt index c5f61c8a..b1c910e5 100644 --- a/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/WordAdapter.kt @@ -5,12 +5,26 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView class WordAdapter( - val wordList: List, val onItemClicked: (SearchWord) -> Unit -): RecyclerView.Adapter() { +): ListAdapter( + object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: SearchWord, newItem: SearchWord): Boolean { + return (oldItem.name == newItem.name) + && (oldItem.address == newItem.address) + && (oldItem.type == newItem.type) + } + + override fun areContentsTheSame(oldItem: SearchWord, newItem: SearchWord): Boolean { + return oldItem == newItem + } + + } +) { inner class ViewHolder( itemView: View ): RecyclerView.ViewHolder(itemView) { @@ -18,9 +32,7 @@ class WordAdapter( val delete: ImageView = itemView.findViewById(R.id.x) init { delete.setOnClickListener { - val position = bindingAdapterPosition - val word:SearchWord = wordList[position] - onItemClicked(word) + deletedWords(bindingAdapterPosition) } } } @@ -29,11 +41,13 @@ class WordAdapter( return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.word_item, parent, false)) } - override fun getItemCount(): Int { - return wordList.size + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val word = getItem(position) + holder.searchWord.text = word.name } - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.searchWord.text = wordList[position].name + private val deletedWords = { position:Int -> + val word = getItem(position) + onItemClicked(word) } } \ No newline at end of file