From e112db0c3fc0712bce71b1bdbf3341a5fb259031 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Wed, 24 Jul 2024 01:40:25 +0900 Subject: [PATCH 01/32] =?UTF-8?q?4=EC=A3=BC=EC=B0=A8=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기본 코드 준비 --- app/build.gradle.kts | 12 ++ .../tech/kakao/map/DataSearchActivityTest.kt | 26 ++++ .../tech/kakao/map/HomeMapActivityTest.kt | 65 ++++++++ .../tech/kakao/map/MapErrorActivityTest.kt | 33 ++++ app/src/main/AndroidManifest.xml | 13 +- .../java/campus/tech/kakao/map/Application.kt | 14 ++ .../campus/tech/kakao/map/MainActivity.kt | 11 -- .../tech/kakao/map/MapViewModelFactory.kt | 16 ++ .../tech/kakao/map/PreferenceRepository.kt | 18 +++ .../kakao/map/activity/DataSearchActivity.kt | 137 +++++++++++++++++ .../kakao/map/activity/HomeMapActivity.kt | 144 ++++++++++++++++++ .../kakao/map/activity/MapErrorActivity.kt | 36 +++++ .../kakao/map/adapter/RecentSearchAdapter.kt | 45 ++++++ .../kakao/map/adapter/SearchDataAdapter.kt | 60 ++++++++ .../tech/kakao/map/dBHelper/RecentDBHelper.kt | 28 ++++ .../tech/kakao/map/data/RecentSearchData.kt | 4 + .../map/dataContract/LocationDataContract.kt | 8 + .../map/dataContract/RecentDataContract.kt | 10 ++ .../dataRepository/RecentDataRepository.kt | 71 +++++++++ .../dataRepository/SearchDataRepository.kt | 40 +++++ .../map/listener/RecentAdapterListener.kt | 5 + .../map/listener/SearchAdapterListener.kt | 5 + .../tech/kakao/map/retrofit/Category.kt | 25 +++ .../kakao/map/retrofit/MapSearchResponse.kt | 19 +++ .../tech/kakao/map/retrofit/RetrofitAPI.kt | 42 +++++ .../kakao/map/retrofit/RetrofitService.kt | 14 ++ .../tech/kakao/map/viewModel/MapViewModel.kt | 17 +++ .../kakao/map/viewModel/RecentViewModel.kt | 47 ++++++ .../kakao/map/viewModel/SearchViewModel.kt | 17 +++ app/src/main/res/drawable/loading_icon.xml | 13 ++ .../main/res/drawable/location_map_icon.xml | 9 ++ app/src/main/res/drawable/map_label.png | Bin 0 -> 8726 bytes app/src/main/res/drawable/no_search.xml | 7 + app/src/main/res/drawable/reload_icon.xml | 12 ++ app/src/main/res/drawable/search_icon.xml | 10 ++ .../main/res/layout/activity_data_search.xml | 70 +++++++++ app/src/main/res/layout/activity_home_map.xml | 55 +++++++ app/src/main/res/layout/activity_main.xml | 19 --- .../main/res/layout/activity_map_error.xml | 52 +++++++ .../res/layout/map_detail_bottom_sheet.xml | 33 ++++ .../main/res/layout/recent_search_item.xml | 33 ++++ app/src/main/res/layout/search_data_item.xml | 76 +++++++++ app/src/main/res/values/mycolors.xml | 5 + app/src/main/res/values/mystrings.xml | 10 ++ 44 files changed, 1355 insertions(+), 31 deletions(-) create mode 100644 app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt create mode 100644 app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt create mode 100644 app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/Application.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/MainActivity.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/retrofit/Category.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/retrofit/MapSearchResponse.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitService.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt create mode 100644 app/src/main/res/drawable/loading_icon.xml create mode 100644 app/src/main/res/drawable/location_map_icon.xml create mode 100644 app/src/main/res/drawable/map_label.png create mode 100644 app/src/main/res/drawable/no_search.xml create mode 100644 app/src/main/res/drawable/reload_icon.xml create mode 100644 app/src/main/res/drawable/search_icon.xml create mode 100644 app/src/main/res/layout/activity_data_search.xml create mode 100644 app/src/main/res/layout/activity_home_map.xml delete mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_map_error.xml create mode 100644 app/src/main/res/layout/map_detail_bottom_sheet.xml create mode 100644 app/src/main/res/layout/recent_search_item.xml create mode 100644 app/src/main/res/layout/search_data_item.xml create mode 100644 app/src/main/res/values/mycolors.xml create mode 100644 app/src/main/res/values/mystrings.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2c1a15f2..cedf7967 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties + plugins { id("com.android.application") id("org.jetbrains.kotlin.android") @@ -12,6 +14,12 @@ android { compileSdk = 34 defaultConfig { + ndk { + abiFilters.add("arm64-v8a") + abiFilters.add("armeabi-v7a") + abiFilters.add("x86") + abiFilters.add("x86_64") + } applicationId = "campus.tech.kakao.map" minSdk = 26 targetSdk = 34 @@ -19,6 +27,9 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + resValue("string", "kakao_api_key", getApiKey("KAKAO_API_KEY")) + buildConfigField("String", "KAKAO_REST_API_KEY", getApiKey("KAKAO_REST_API_KEY")) } buildTypes { @@ -43,6 +54,7 @@ android { buildConfig = true } } +fun getApiKey(key: String): String = gradleLocalProperties(rootDir, providers).getProperty(key) dependencies { diff --git a/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt new file mode 100644 index 00000000..bae3afeb --- /dev/null +++ b/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt @@ -0,0 +1,26 @@ +package campus.tech.kakao.map + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.closeSoftKeyboard +import androidx.test.espresso.action.ViewActions.replaceText +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.ActivityScenarioRule +import campus.tech.kakao.map.activity.DataSearchActivity +import org.junit.Rule +import org.junit.Test + + +class DataSearchActivityTest { + @get:Rule + val activityRule = ActivityScenarioRule(DataSearchActivity::class.java) + + @Test + fun 검색어_입력시_검색_결과가_나타남() { + onView(withId(R.id.searchBar)) + .perform(replaceText("전남대학교"), closeSoftKeyboard()) + onView(withId(R.id.searchResulListView)) + .check(matches(isDisplayed())) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt new file mode 100644 index 00000000..1a13f135 --- /dev/null +++ b/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt @@ -0,0 +1,65 @@ +package campus.tech.kakao.map + +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.intent.Intents.init +import androidx.test.espresso.intent.Intents.intended +import androidx.test.espresso.intent.Intents.release +import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.rules.ActivityScenarioRule +import campus.tech.kakao.map.activity.DataSearchActivity +import campus.tech.kakao.map.activity.HomeMapActivity +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +class HomeMapActivityTest { + @get:Rule + val activityRule: ActivityScenarioRule = + ActivityScenarioRule( + Intent( + ApplicationProvider.getApplicationContext(), + HomeMapActivity::class.java + ).apply { + putExtra("name", "전남대학교 여수캠퍼스") + putExtra("address", "전라남도 여수시 대학로 50") + putExtra("latitude", "34.772884563341") + putExtra("longitude", "127.69954169563") + } + ) + + @Before + fun setup() { + init() + } + + @After + fun teardown() { + release() + } + + @Test + fun 목록에서_선택한_장소의_정보가_BottomSheet에_나타남() { + onView(withId(R.id.placeName)) + .check(matches(withText("전남대학교 여수캠퍼스"))) + onView(withId(R.id.placeAddress)) + .check(matches(withText("전라남도 여수시 대학로 50"))) + onView(withId(R.id.bottomSheet)) + .check(matches(isDisplayed())) + } + + @Test + fun 검색바를_클릭하면_검색화면으로_이동() { + onView(withId(R.id.search_home)) + .perform(click()) + intended(hasComponent(DataSearchActivity::class.java.name)) + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt new file mode 100644 index 00000000..b6ce747d --- /dev/null +++ b/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt @@ -0,0 +1,33 @@ +package campus.tech.kakao.map + +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.rules.ActivityScenarioRule +import campus.tech.kakao.map.activity.HomeMapActivity +import campus.tech.kakao.map.activity.MapErrorActivity +import org.junit.Rule +import org.junit.Test + + +class MapErrorActivityTest { + @get:Rule + val activityRule : ActivityScenarioRule = + ActivityScenarioRule( + Intent( + ApplicationProvider.getApplicationContext(), + MapErrorActivity::class.java + ).apply { + putExtra("errorMessage","java.lang.Exception:401") + } + ) + + @Test + fun onMapError_예외설명_에러화면에_나타남() { + onView(withId(R.id.error_detail)) + .check(matches(withText("401"))) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6bca2f54..d8f7a418 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,10 @@ + + + @@ -21,6 +28,10 @@ + diff --git a/app/src/main/java/campus/tech/kakao/map/Application.kt b/app/src/main/java/campus/tech/kakao/map/Application.kt new file mode 100644 index 00000000..dbd2084a --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/Application.kt @@ -0,0 +1,14 @@ +package campus.tech.kakao.map + +import android.app.Application +import com.kakao.vectormap.KakaoMapSdk + +class Application : Application() { + override fun onCreate(){ + super.onCreate() + + //카카오맵 SDK 초기화 + val key = getString(R.string.kakao_api_key) + KakaoMapSdk.init(this, key) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/MainActivity.kt deleted file mode 100644 index 95b43803..00000000 --- a/app/src/main/java/campus/tech/kakao/map/MainActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package campus.tech.kakao.map - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} diff --git a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt new file mode 100644 index 00000000..6a3098e6 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt @@ -0,0 +1,16 @@ +package campus.tech.kakao.map + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.viewModel.MapViewModel +import java.lang.IllegalArgumentException + +class MapViewModelFactory(repository: PreferenceRepository): ViewModelProvider.Factory { + private val prefersRepo = repository + override fun create(modelClass: Class): T { + if(modelClass.isAssignableFrom(MapViewModel::class.java)){ + return MapViewModel(prefersRepo) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt b/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt new file mode 100644 index 00000000..fcb845bd --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt @@ -0,0 +1,18 @@ +package campus.tech.kakao.map + +import android.content.Context +import android.content.SharedPreferences + +class PreferenceRepository(context: Context) { + + private var sharedPrefs: SharedPreferences = + context.getSharedPreferences("location_data", Context.MODE_PRIVATE) + + fun setString(key: String, value: String) { + sharedPrefs.edit().putString(key, value).apply() + } + + fun getString(key: String, value: String?): String { + return sharedPrefs.getString(key, value).toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt new file mode 100644 index 00000000..d3e05af5 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt @@ -0,0 +1,137 @@ +package campus.tech.kakao.map.activity + +import android.annotation.SuppressLint +import android.content.Intent +import android.health.connect.datatypes.ExerciseRoute.Location +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import android.widget.EditText +import android.widget.ImageButton +import android.widget.TextView +import androidx.activity.OnBackPressedCallback +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.R +import campus.tech.kakao.map.listener.RecentAdapterListener +import campus.tech.kakao.map.listener.SearchAdapterListener +import campus.tech.kakao.map.adapter.RecentSearchAdapter +import campus.tech.kakao.map.adapter.SearchDataAdapter +import campus.tech.kakao.map.dataContract.LocationDataContract +import campus.tech.kakao.map.viewModel.RecentViewModel +import campus.tech.kakao.map.viewModel.SearchViewModel + +class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAdapterListener { + private lateinit var searchViewModel: SearchViewModel + private lateinit var recentViewModel: RecentViewModel + private lateinit var editText: EditText + private lateinit var resultDataAdapter: SearchDataAdapter + private lateinit var searchDataListView: RecyclerView + private lateinit var recentSearchListView: RecyclerView + private lateinit var noResultNotice: TextView + private lateinit var deleteBtn: ImageButton + + + @SuppressLint("MissingInflatedId") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_data_search) + + //View 초기화 + searchDataListView = findViewById(R.id.searchResulListView) + editText = findViewById(R.id.searchBar) + noResultNotice = findViewById(R.id.noResult) + deleteBtn = findViewById(R.id.deleteInput) + recentSearchListView = findViewById(R.id.recentSearchListView) + + //ViewModel 생성 + searchViewModel = ViewModelProvider(this)[SearchViewModel::class.java] + recentViewModel = ViewModelProvider(this)[RecentViewModel::class.java] + + //검색 결과 목록 세로 스크롤 설정 + searchDataListView.layoutManager = LinearLayoutManager(this) + //최근 검색어 목록 가로 스크롤 설정 + recentSearchListView.layoutManager = + LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) + + //어뎁터 초기화 + resultDataAdapter = SearchDataAdapter(emptyList(), recentViewModel, this) + searchDataListView.adapter = resultDataAdapter + + resetButtonListener() + setTextWatcher() + + recentViewModel.getRecentDataLiveData().observe(this, Observer { recentData -> + recentSearchListView.adapter = RecentSearchAdapter(recentData, recentViewModel, this) + }) + + searchViewModel.searchResults.observe(this, Observer { documentsList -> + if (documentsList.isNotEmpty()) { + noResultNotice.visibility = View.GONE + resultDataAdapter.updateData(documentsList) + } else { + noResultNotice.visibility = View.VISIBLE + resultDataAdapter.updateData(emptyList()) + } + }) + + val onBackPressedCallback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + val intent = Intent(this@DataSearchActivity, HomeMapActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + startActivity(intent) + } + } + this.onBackPressedDispatcher.addCallback(this, onBackPressedCallback) + } + + private fun setTextWatcher() { + editText.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 searchInput = editText.text.trim().toString() + + if (searchInput.isNotEmpty()) { + searchViewModel.loadResultData(searchInput) + } else { + noResultNotice.visibility = View.VISIBLE + resultDataAdapter.updateData(emptyList()) + } + } + + override fun afterTextChanged(s: Editable?) { + } + }) + } + + private fun resetButtonListener() { + deleteBtn.setOnClickListener { + editText.text.clear() + } + } + + //클릭한 검색어가 자동으로 입력되는 기능 구현 + override fun autoSearch(searchData: String) { + editText.setText(searchData) + } + + override fun displaySearchLocation( + name: String, + address: String, + latitude: String, + longitude: String + ) { + val intent = Intent(this@DataSearchActivity, HomeMapActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + intent.putExtra(LocationDataContract.LOCATION_NAME, name) + intent.putExtra(LocationDataContract.LOCATION_ADDRESS, address) + intent.putExtra(LocationDataContract.LOCATION_LATITUDE, latitude) + intent.putExtra(LocationDataContract.LOCATION_LONGITUDE, longitude) + startActivity(intent) + } +} diff --git a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt new file mode 100644 index 00000000..8c63c015 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt @@ -0,0 +1,144 @@ +package campus.tech.kakao.map.activity + +import android.annotation.SuppressLint +import android.content.Intent +import android.graphics.Color +import android.os.Bundle +import android.widget.EditText +import android.widget.TextView +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.MapViewModelFactory +import campus.tech.kakao.map.PreferenceRepository +import campus.tech.kakao.map.R +import campus.tech.kakao.map.dataContract.LocationDataContract +import campus.tech.kakao.map.viewModel.MapViewModel +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.kakao.vectormap.KakaoMap +import com.kakao.vectormap.KakaoMapReadyCallback +import com.kakao.vectormap.LatLng +import com.kakao.vectormap.MapLifeCycleCallback +import com.kakao.vectormap.MapView +import com.kakao.vectormap.label.LabelOptions +import com.kakao.vectormap.label.LabelStyle +import com.kakao.vectormap.label.LabelStyles + +class HomeMapActivity : AppCompatActivity() { + private lateinit var mapView: MapView + private lateinit var searchBar: EditText + private val bottomSheet: ConstraintLayout by lazy { findViewById(R.id.bottomSheet) } + private lateinit var bottomBehavior: BottomSheetBehavior + private lateinit var placeNameTextView: TextView + private lateinit var placeAddressTextView: TextView + private lateinit var mapViewModel: MapViewModel + private lateinit var prefersRepo: PreferenceRepository + + @SuppressLint("MissingInflatedId") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_home_map) + + prefersRepo = PreferenceRepository(applicationContext) + mapViewModel = + ViewModelProvider(this, MapViewModelFactory(prefersRepo))[MapViewModel::class.java] + + val name = intent.getStringExtra(LocationDataContract.LOCATION_NAME) + val address = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS) + val latitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() + val longitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() + + mapView = findViewById(R.id.mapView) + placeNameTextView = findViewById(R.id.placeName) + placeAddressTextView = findViewById(R.id.placeAddress) + + bottomBehavior = BottomSheetBehavior.from(bottomSheet) + val intentError = Intent(this, MapErrorActivity::class.java) + + //KaKao Map UI에 띄우기 + mapView.start(object : MapLifeCycleCallback() { + override fun onMapDestroy() { + } + + override fun onMapError(p0: Exception?) { + intentError.putExtra("errorMessage", p0.toString()) + startActivity(intentError) + } + + }, object : KakaoMapReadyCallback() { + override fun onMapReady(p0: KakaoMap) { + + // 라벨 생성 + if (latitude != null && longitude != null) { + p0.labelManager + val style = + p0.labelManager?.addLabelStyles( + LabelStyles.from( + LabelStyle.from(R.drawable.map_label).setTextStyles( + 35, + Color.BLACK, 1, Color.RED + ) + ) + ) + val options = + LabelOptions.from(LatLng.from(latitude, longitude)).setStyles(style) + .setTexts(name) + val layer = p0.labelManager?.layer + layer?.addLabel(options) + } + } + + // 지도 시작 시 위치 좌표 설정 + override fun getPosition(): LatLng { + val savedLatitude = + mapViewModel.getLocation(LocationDataContract.LOCATION_LATITUDE, null) + .toDoubleOrNull() + val savedLongitude = + mapViewModel.getLocation(LocationDataContract.LOCATION_LONGITUDE, null) + .toDoubleOrNull() + + return if (latitude != null && longitude != null) { + LatLng.from(latitude, longitude) + } else if (savedLatitude != null && savedLongitude != null) { + LatLng.from(savedLatitude, savedLongitude) + } else { + super.getPosition() + } + } + }) + + if (latitude != null && longitude != null) { + placeNameTextView.text = name + placeAddressTextView.text = address + bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED + } else { + bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN + } + + searchBar = findViewById(R.id.search_home) + searchBar.setOnClickListener { + val intent = Intent(this, DataSearchActivity::class.java) + startActivity(intent) + } + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onPause() { + super.onPause() + mapView.pause() + } + + override fun onDestroy() { + super.onDestroy() + intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE) + ?.let { mapViewModel.saveLocation(LocationDataContract.LOCATION_LATITUDE, it) } + intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE) + ?.let { mapViewModel.saveLocation(LocationDataContract.LOCATION_LONGITUDE, it) } + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt new file mode 100644 index 00000000..8e981742 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt @@ -0,0 +1,36 @@ +package campus.tech.kakao.map.activity + +import android.os.Bundle +import android.util.Log +import android.widget.TextView +import android.window.OnBackInvokedDispatcher +import androidx.activity.OnBackPressedCallback +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import campus.tech.kakao.map.R + +class MapErrorActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_map_error) + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) + insets + } + + //전달 받은 에러 메세지에서 임의로 내용 일부 추출 + val errorMessage = intent.getStringExtra("errorMessage")?.substringAfterLast(":") + val errorTextView = findViewById(R.id.error_detail) + errorTextView.text = errorMessage + + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + finishAffinity() + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt new file mode 100644 index 00000000..ac2572fa --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt @@ -0,0 +1,45 @@ +package campus.tech.kakao.map.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageButton +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.data.RecentSearchData +import campus.tech.kakao.map.R +import campus.tech.kakao.map.listener.RecentAdapterListener +import campus.tech.kakao.map.viewModel.RecentViewModel + +class RecentSearchAdapter( + private val recentDataList: List, + private val viewModel: RecentViewModel, + private val adapterListener: RecentAdapterListener +) : RecyclerView.Adapter() { + + class RecentViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val name: TextView = view.findViewById(R.id.recent_search) + val deleteBtn: ImageButton = view.findViewById(R.id.delete_recent) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view = + LayoutInflater.from(parent.context).inflate(R.layout.recent_search_item, parent, false) + return RecentViewHolder(view) + } + + override fun getItemCount(): Int = recentDataList.count() + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val item = recentDataList[position] + val viewHolder = holder as RecentViewHolder + viewHolder.name.text = item.name + viewHolder.deleteBtn.setOnClickListener { + viewModel.deleteRecentData(item.name, item.address) + } + + viewHolder.name.setOnClickListener { + adapterListener.autoSearch(item.name) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt new file mode 100644 index 00000000..254808c3 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt @@ -0,0 +1,60 @@ +package campus.tech.kakao.map.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.R +import campus.tech.kakao.map.listener.SearchAdapterListener +import campus.tech.kakao.map.viewModel.RecentViewModel +import campus.tech.kakao.map.retrofit.Document + +class SearchDataAdapter( + private var items: List, + private val recentViewModel: RecentViewModel, + private var adapterListener: SearchAdapterListener +) : RecyclerView.Adapter() { + + class SearchDataViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val name: TextView = view.findViewById(R.id.search_data_name) + val address: TextView = view.findViewById(R.id.search_data_address) + val category: TextView = view.findViewById(R.id.search_data_category) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view = + LayoutInflater.from(parent.context).inflate(R.layout.search_data_item, parent, false) + return SearchDataViewHolder(view) + } + + override fun getItemCount(): Int = items.count() + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val item = items[position] + val viewHolder = holder as SearchDataViewHolder + viewHolder.name.text = item.name + viewHolder.address.text = item.address + // API 데이터에 "category_group_code"가 있는 경우 해당 그룹 코드에 맞는 설명을 출력하고, 비어 있는 경우 "category_name"의 일부 문자열을 출력 + if (item.categoryCode.isEmpty()) { + viewHolder.category.text = item.categoryTail + } else { + viewHolder.category.text = item.categoryDescription + } + holder.itemView.setOnClickListener { + val searchTime = System.currentTimeMillis() + recentViewModel.addRecentData(item.name, item.address, searchTime) + adapterListener.displaySearchLocation( + item.name, + item.address, + item.latitude, + item.longitude + ) + } + } + + fun updateData(newItems: List) { + items = newItems + notifyDataSetChanged() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt b/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt new file mode 100644 index 00000000..744b568f --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt @@ -0,0 +1,28 @@ +package campus.tech.kakao.map.dBHelper + +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import campus.tech.kakao.map.dataContract.RecentDataContract + +//version 2: DB에 time 컬럼을 추가함 +//version 3" DB에 address 컬럼을 추가함 +class RecentDBHelper(context: Context) : SQLiteOpenHelper(context, "RecentData.db", null, 3) { + override fun onCreate(db: SQLiteDatabase?) { + createRecentDataTable(db) + } + + override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { + db?.execSQL("DROP TABLE IF EXISTS ${RecentDataContract.TABLE_NAME}") + createRecentDataTable(db) + } + + private fun createRecentDataTable(db: SQLiteDatabase?) { + db?.execSQL( + "CREATE TABLE ${RecentDataContract.TABLE_NAME} (" + + "${RecentDataContract.TABLE_COLUMN_NAME} varchar(30) NOT NULL, " + + "${RecentDataContract.TABLE_COLUMN_ADDRESS} varchar(50) NOT NULL, " + + "${RecentDataContract.TABLE_COLUMN_TIME} integer NOT NULL);" + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt b/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt new file mode 100644 index 00000000..31bddf16 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt @@ -0,0 +1,4 @@ +package campus.tech.kakao.map.data + + +data class RecentSearchData(val name: String, val address: String, val time: Long) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt b/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt new file mode 100644 index 00000000..1fc74189 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt @@ -0,0 +1,8 @@ +package campus.tech.kakao.map.dataContract + +object LocationDataContract { + const val LOCATION_NAME = "name" + const val LOCATION_ADDRESS = "address" + const val LOCATION_LATITUDE = "latitude" + const val LOCATION_LONGITUDE = "longitude" +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt b/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt new file mode 100644 index 00000000..352f38a9 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt @@ -0,0 +1,10 @@ +package campus.tech.kakao.map.dataContract + +import android.provider.BaseColumns + +object RecentDataContract : BaseColumns { + const val TABLE_NAME = "RecentData" + const val TABLE_COLUMN_NAME = "name" + const val TABLE_COLUMN_ADDRESS = "address" + const val TABLE_COLUMN_TIME = "recentSearchTime" +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt new file mode 100644 index 00000000..97d7279a --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt @@ -0,0 +1,71 @@ +package campus.tech.kakao.map.dataRepository + +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import campus.tech.kakao.map.dBHelper.RecentDBHelper +import campus.tech.kakao.map.dataContract.RecentDataContract +import campus.tech.kakao.map.data.RecentSearchData + +class RecentDataRepository(context: Context) { + private val db: RecentDBHelper = RecentDBHelper(context) + private val wDb = db.writableDatabase + private val rDb = db.readableDatabase + + fun insertSearchData(data: RecentSearchData) { + val cv = ContentValues().apply { + put(RecentDataContract.TABLE_COLUMN_NAME, data.name) + put(RecentDataContract.TABLE_COLUMN_ADDRESS, data.address) + put(RecentDataContract.TABLE_COLUMN_TIME, data.time) + } + wDb.insert(RecentDataContract.TABLE_NAME, null, cv) + } + + fun getRecentSearchDataList(): List { + val cursor: Cursor = rDb.query( + RecentDataContract.TABLE_NAME, + null, + null, + null, + null, + null, + "${RecentDataContract.TABLE_COLUMN_TIME} DESC" + ) + val recentDataList = mutableListOf() + + while (cursor.moveToNext()) { + val name = + cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_NAME)) + val address = + cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_ADDRESS)) + val time = + cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_TIME)) + + recentDataList.add(RecentSearchData(name, address, time.toLong())) + } + cursor.close() + + return recentDataList + } + + fun deleteSearchData(data: String, address: String) { + wDb.delete( + RecentDataContract.TABLE_NAME, + "${RecentDataContract.TABLE_COLUMN_NAME} = ? AND ${RecentDataContract.TABLE_COLUMN_ADDRESS} = ?", + arrayOf(data, address) + ) + } + + fun updateTime(data: RecentSearchData) { + val cv = ContentValues().apply { + put(RecentDataContract.TABLE_COLUMN_TIME, data.time) + } + + wDb.update( + RecentDataContract.TABLE_NAME, + cv, + "${RecentDataContract.TABLE_COLUMN_NAME} = ?", + arrayOf(data.name) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt new file mode 100644 index 00000000..acab6899 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt @@ -0,0 +1,40 @@ +package campus.tech.kakao.map.dataRepository + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import campus.tech.kakao.map.retrofit.CategoryData +import campus.tech.kakao.map.retrofit.Document +import campus.tech.kakao.map.retrofit.RetrofitAPI.getResultFromAPI + +class SearchDataRepository(){ + private val _searchDataList = MutableLiveData>() + val searchResults: LiveData> + get() = _searchDataList + + //검색 결과 가공 후 LiveData에 저장 + fun loadResultMapData(data: String) { + getResultFromAPI(data) { response -> + if (response.isSuccessful) { + val body = response.body() + body?.documents?.let { documents -> + val updatedDocuments = documents.map { document -> + val descriptionFromCode = CategoryData.descriptions[document.categoryCode] + val descriptionFromCategory = getTailCategory(document.category) + val updateDocument = document.copy( + categoryDescription = descriptionFromCode, + categoryTail = descriptionFromCategory + ) + updateDocument + } + _searchDataList.postValue(updatedDocuments) + } + } + } + } + + //API 데이터에서 "category_name" 문자열이 길기 때문에, 충분한 의미 전달이 되는 키워드를 임의로 추출 + private fun getTailCategory(category: String): String { + val parts = category.split(">") + return if (parts.size > 1) parts[1].trim() else parts.last().trim() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt new file mode 100644 index 00000000..05716243 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt @@ -0,0 +1,5 @@ +package campus.tech.kakao.map.listener + +interface RecentAdapterListener { + fun autoSearch(searchData: String) +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt new file mode 100644 index 00000000..11481426 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt @@ -0,0 +1,5 @@ +package campus.tech.kakao.map.listener + +interface SearchAdapterListener { + fun displaySearchLocation(name: String, address: String, latitude: String, longitude: String) +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/Category.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/Category.kt new file mode 100644 index 00000000..4d74236d --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/Category.kt @@ -0,0 +1,25 @@ +package campus.tech.kakao.map.retrofit + +// "category_group_code"와 설명을 매칭하기 위한 객체 +object CategoryData { + val descriptions = mapOf( + "MT1" to "대형마트", + "CS2" to "편의점", + "PS3" to "어린이집, 유치원", + "SC4" to "학교", + "AC5" to "학원", + "PK6" to "주차장", + "OL7" to "주유소, 충전소", + "SW8" to "지하철역", + "BK9" to "은행", + "CT1" to "문화시설", + "AG2" to "중개업소", + "PO3" to "공공기관", + "AT4" to "관광명소", + "AD5" to "숙박", + "FD6" to "음식점", + "CE7" to "카페", + "HP8" to "병원", + "PM9" to "약국" + ) +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/MapSearchResponse.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/MapSearchResponse.kt new file mode 100644 index 00000000..75f3d734 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/MapSearchResponse.kt @@ -0,0 +1,19 @@ +package campus.tech.kakao.map.retrofit + +import com.google.gson.annotations.SerializedName + +data class Document( + @SerializedName("place_name") val name: String, + @SerializedName("category_name") val category: String, + @SerializedName("address_name") val address: String, + @SerializedName("category_group_code") val categoryCode: String, + @SerializedName("x") val longitude: String, + @SerializedName("y") val latitude: String, + var categoryDescription: String? = null, + var categoryTail: String? = null +) + +data class MapSearchResponse( + @SerializedName("documents") val documents: List +) + diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt new file mode 100644 index 00000000..200f12fb --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt @@ -0,0 +1,42 @@ +package campus.tech.kakao.map.retrofit + +import android.util.Log +import campus.tech.kakao.map.BuildConfig +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object RetrofitAPI { + //실제 사용될 때 Retrofit 객체 생성 + val retrofitService: RetrofitService by lazy { + Log.d("yeong", "Use Retrofit!") + Retrofit.Builder() + .baseUrl("https://dapi.kakao.com/v2/local/search/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(RetrofitService::class.java) + } + + //카카오맵 API 검색 결과 + fun getResultFromAPI(keyword: String, callback: (Response) -> Unit) { + val apiKey = "KakaoAK ${BuildConfig.KAKAO_REST_API_KEY}" + + retrofitService.requestResults(apiKey, keyword) + .enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + callback(response) + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.d("API", "error : $t") + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitService.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitService.kt new file mode 100644 index 00000000..1315bf19 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitService.kt @@ -0,0 +1,14 @@ +package campus.tech.kakao.map.retrofit + +import retrofit2.Call +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Query + +interface RetrofitService { + @GET("keyword.json") + fun requestResults( + @Header("Authorization") apiKey: String, + @Query("query") query: String + ): Call +} diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt new file mode 100644 index 00000000..c9c3a35f --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt @@ -0,0 +1,17 @@ +package campus.tech.kakao.map.viewModel + +import androidx.lifecycle.ViewModel +import campus.tech.kakao.map.PreferenceRepository + + +class MapViewModel(repository: PreferenceRepository) : ViewModel() { + private val prefersRepo = repository + + fun saveLocation(locationKey: String, data: String) { + prefersRepo.setString(locationKey, data) + } + + fun getLocation(locationKey: String, data: String?): String { + return prefersRepo.getString(locationKey, data) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt new file mode 100644 index 00000000..0118a719 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt @@ -0,0 +1,47 @@ +package campus.tech.kakao.map.viewModel + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import campus.tech.kakao.map.dataRepository.RecentDataRepository +import campus.tech.kakao.map.data.RecentSearchData + +class RecentViewModel(application: Application) : AndroidViewModel(application) { + private val repository: RecentDataRepository = RecentDataRepository(application) + + private val _recentDataList = MutableLiveData>() + + init { + _recentDataList.value = repository.getRecentSearchDataList() + } + + fun addRecentData(data: String, address: String, time: Long) { + val currentList = _recentDataList.value.orEmpty().toMutableList() + val selectData = RecentSearchData(data, address, time) + + if (checkExist(currentList, selectData)) { + repository.insertSearchData(selectData) + } else { + repository.updateTime(selectData) + } + _recentDataList.value = repository.getRecentSearchDataList() + } + + //DB에 데이터 추가 전 중복 검사 (현재 DB에 없으면 true) + private fun checkExist( + currentList: MutableList, + data: RecentSearchData + ): Boolean { + return !currentList.any { it.name == data.name && it.address == data.address } + } + + fun getRecentDataLiveData(): LiveData> { + return _recentDataList + } + + fun deleteRecentData(data: String, address: String) { + repository.deleteSearchData(data, address) + _recentDataList.value = repository.getRecentSearchDataList() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt new file mode 100644 index 00000000..de93474c --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt @@ -0,0 +1,17 @@ +package campus.tech.kakao.map.viewModel + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import campus.tech.kakao.map.dataRepository.SearchDataRepository + +class SearchViewModel(application: Application) : AndroidViewModel(application) { + private val repository: SearchDataRepository = SearchDataRepository() + + //"DataSearchActivity"에서 사용할 LiveData + val searchResults = repository.searchResults + + //검색 결과를 LiveData에 저장 + fun loadResultData(searchQuery:String){ + repository.loadResultMapData(searchQuery) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_icon.xml b/app/src/main/res/drawable/loading_icon.xml new file mode 100644 index 00000000..42277f69 --- /dev/null +++ b/app/src/main/res/drawable/loading_icon.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/location_map_icon.xml b/app/src/main/res/drawable/location_map_icon.xml new file mode 100644 index 00000000..21e1b4e6 --- /dev/null +++ b/app/src/main/res/drawable/location_map_icon.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/map_label.png b/app/src/main/res/drawable/map_label.png new file mode 100644 index 0000000000000000000000000000000000000000..9f7f4b27ec693a986576b5059dc0f593597d1b9e GIT binary patch literal 8726 zcmZ`<1yGbxyIz(hMPUV`Lpp?|J0+xh=>=9w=>~zN47x>WkY-8gW(5R6S_#PoBqSH4 z^IzxA+?jvo-uce=o%v43d(L~F=RMJSI?wJC(-H#!fcxrd$_7|J?B7d>kNx(_!M|fY zW?MA_Z2%yU0~`JZ0J!`YzXbsJ3IG7xHUNNBIsicBk=>>*gN?v{uK7$EaQE-Y?<`Hl zh7kCuYpW1!5s*EQAp5B$3B{Ios;;bP6fn1!^QzW<0JbdOEw{OFvKQ-+tD5rco)wCf zbr&EerY=BDo?`S>OyY$lC6AE-5%*L0kOajWHZ&VL%#_PTqWHLL3bL*jn`7&uTsBlz!d?H9@|b+RWa!zPp_1zCCdd zw`h6$U+#PdPjdIcuDDK)#6AH}1hDLRTz<@*e5pTbmdYal7pD47lTFwtpvL7It($gm$&67;Q8sU4H z0*}ec#Q9hL$NdKqVBi$3htY}~+UokwonRx(GylQ+@Y=to_&>fIn`+CPFk6@8=~WhLkZ6DuX!K`-X;cUAjSm61PnFL z&2Ay9sj_zUBp2)%7e>VzcQ~=J)IiU5uKSk1L-j+(YXb%`g5k>sQ)A323tA81FKEy| zqt_rmr=h%2!K|3XFn7EX()Pp|8_IKAw2A(WxAL5{E>-Ukq0%6rbibR52Czf_eepQ9!l>4 zuEHqM?@@BR&>j%$OCcl$5Ovt^=dG7NO)YP5P~Akior{3T4Z-$q&L z4g}3M+{`x2c0yk>X>YdDu}`L=uJmteqxu>rq~b^RKEWeC*@Q)68;2q1@UUEYc39C> zH{<{6UhWHRM#yorj@mSO^NeNnoj1_jKQ{Oet;)A^uu`gsG zh;Dog5mG#PI|ew2Pfq+O-6`kNi5{m$IbYzbcr%uoR0oXgUe+7CNDxGBJJFlM2=i=IaG2;3wZta^S)vi9z6T<6s!yBkA z8#!om;gc&-WDfvluM1!`Xht63EaCpVd}ReCiW@B1X*{lu_H=l*4d*6&s^I3+bH$d< zF+I1gDva=R%}G-gt{Z(DWb=jtlLury@Yl(L!PW)R(I^@;t#&9$028KDLGQQ{sM@DJ zgFIaPkvcrRQ!GFToVv+9U3|=9H$7LZ$|~7h*RN3z^+T5E7B~RA%P=*E&jys>5xC9y zG`4z>%z>~x;4OEKMXL*@k4M%nQ_mcx#)aCYGsQzUuXi$o!HQ7PL6@eSKEJA8)A4>;swryOW~q`?5}R>;i5L0()I{-~>jEAp2I>R6 zlpIJ(VRQa01L`*{EJ1s*NQ2mdtqS+NwZn_Ir^WFjLKjkFPcVk~xjIP@`aT+0Yx#-A zvvBOZ5!}MTBm30YdS(6DxbPGkX3D9+mEL}xQ$zgjZtcZ;?_QR?Op>I^-!Aq@cru-H zcWCfss(>r2d}d)`wk)Fz+B=>u%Os7bR;kU@-C>jWS4&U%j1=b%^n!4=VlZHt`rjV6 z6#h_gJQU~p$?dm#UJ4&KpQ4*gTW@_y!qcK%m}H{6_@v{ExT&j1@6WlgoyLXkTI+lb z3eYd3s>~%($uGNVvN1sN{kNo`sHzbi>$YsGrMYT~Ef5XnhWJjD;&h70_pS*5rneb4 z;qA!k7&J*onyis~KkMz(>H<9QdDRY<@9Ze}9`7*dr&TX5cVf~VPMG1n(lhPXvhZT= zPat2Hy8};7`3&!5>4|>07ug%mjRdFXkgvQW#_Xk$k1=kzcLO}SmNQjKd9xo4QIr!k zw2zON!rX^gwK^%-N$Im}8w_|(WG{ewPc*x0Te5>g;DQS-1NJBqr&a&El6)Il&xa%K zuBqm9iO?bC#r8-!vbP-66-K*9e!c9Yc#@qtKxA1+972Y6KUVQ8?64up9cL+dMofew zXg%3XTEFW36=gZFZSF-QQ)j@STxXs6V0P@O_p0?V0s=08)KnV(3$GS4cm32I#0gC= zGa9Oq5pq_tt&7+=*c!+1XcNSRYhrh4`K88_M4-HOf>LC}lB{U*g0S#n;&Y$%&zs`S zbESFR^e#d#VhH|6QZ3nZmOaCxExKtLv@S*a`u><0|JS z)$4}t!7+^6FZtMQPOv)85CbP-lb-a{R1pR#CXTsuT|Lvg!Bt+0k{{|4O>|g7uN81^ zP&LxNJ+x~y=YJkCo{r8fA9Q)uo@_sQ5_m?4(RqCvT}YlF#!M2I;}>wzVX%@IChhNB zilnDwa+dWN*h9c}I5M=c!o_XjCW1ulUVIGC1Ko1MIPcv}$i|MqfV$7Zv3gB2d_EH? zWLVQ|<-hs4mI5D)=Yib+yqTK_adp{gN&6;vFXPut4oeOWk})#{k3({1qhFf&vH;%lx6qzsOV=a`kn0ic(r6H z<)QX<=IW(RQ?+`>_bSD*2J4;aisddZxG;+-&Y$Lb>oCW$Ls+T%!n<2o>DXa){U%xU zw_9DGu9FvF*E|?3(KxHBCCV3?R&FkuU1>Zi)5aBCp-{YnUrIpo2B*zT0u!Do3u{y9 zTa*(kfs;`%)>j%{4G(2%)>W##kxTIB4Ixjzzj=z#ZpxB7njH@h zA#Y`@}=pGk`qDOiymv6Br z1d9c?_r%I~1*mpPM&X>Og_{m}`B$ehQ8pdAYqqPMnU9Y8KesG$Rf%N2TzOP7G_1x~ zrVRg}l*1Z8n`-}h0*{~KY?!;9U-ny-yH+$(8~3x?Jl;qOTCzr zqm8C`#5ok=f+Js1%kL#2=tr6>In&8tNf5#~yFVrNSif&FjB4q3!UxT0u`OBDs4%De7i$>xO@)Ka&BvKYr4CcG41>(6WRd4Ssn zMcZ76%O`1n(-HsS4X$r{&CQw8L|9W0uY3e*>bmJF?_PrRF3w*mGOP)FY z{Ye}Z@FK>dj}uN3ZY$~9@JOY4Tvrn+J})?@Jz6WxD7y7G;(cj9?v7G1z%9r?1uMlOY%9dzl%VI!7Ok^X2`yTVh#9xJ(QN%}I z9Ybf>DA=DaJ#s|@-BAendo1;UxM*6^gbip!6fcNp#<|U6AckubMt4e38zO@vyU-;q zc%!K2akAs>VUwNG4DH+P*kF)znJ@%~8OCQLeZ23VMSzL!RSy*cNej9JxgyCP47qZOjjd~=&Y={Ol0R-gm?Pj9EC`aobPZ{!s zH)Mdc4kkQ=be5|&xT><9vTLJdrR5-eGA^PzKnhj1;B#gz58 zphk6_B#4@w)2tC}kPM^>1sgcJZro!!eu~T9xRPgg5qGjb2OCzvUGd zc*jL}B=!v~H8b+Mjg$%WPxXo7FRDW9O&=2ji7o}ueHr(OPtQf6t`9~81q3Gh>7M$% zHB8%+;Fq}tu_#KC46cL`FS*jij1Ut<>PShQAa+(%tKat~<)>x~k;?D zuY=x$UIG_O>$+*hH76#kcpH*2hC%`hF}5|oO@$wDa{6KQ=jqm#nu5+B95B4`SKYii z?S`Hs-T4nUhYCd-W|G?8$A3jI$~AtYt>}w*ZOa7b_dIbXyemGPA0EAEU9QI1G=EhT zQarQRMgW)bf`bkYxeOc4rHspeZ%}xRwmxt@D(WLgZQ6L~)V@y5TY`k%XQFE1RepoT zo(pknmNR9jbo6MnXGHMkw}+TQV9hg74@My!{psp}BVNNQ!vukgVg1e4NfP(jUpr1S ziS-t5Hg2twRCi1Msa@5Uu`h(09@l56i0Ilq7_SNjb`%S6LkRz%cTPkKNgE_$k#CU# z@j~$u+!46I5ENMFCRzs8&NDN4UVd?R>TWO;y>FstaJc(a!;s3QWgL2JG&fRB7?QCc?k z?GWtcMqu&MJTS!eyFN3XgX;DK1NoXd(_8r^lIzSKXV=YQEEf~RJoyjTWVhY9QEd5~ zH*Wt}4Dnv_CJx-}3lI`EfOsuVZi+Wq@@i|oY7Rv`qnPtU{VKp80(@#+eSGEVRS6|N zTDZg_s|&YD{9%N!;fiwO!?VwOo#69Y)L?ZyK#DwoA)qOk>tRqu+VdmUC zi1i7xA$Zd1m#Z_J?znFd9MUrH2*N0j?J3AkEEqfdqva;uar@pmN1mi*%MKwK^v>4J zW9tHH-A7wb8V%kDeg2eBH6y;;1QAG%jHGx3B{(4JBsJ@)CRz8#(1==1*E!pj#yZ-Haz!gme@rA%Z;7pE)V_&Pl;6 zcKdU5ajeE?Xfr&yZKCjlGx|Dt+l#{F!lTl`0Q z@9lKlG!Y3nFfjEuIDgQ?G1vsMvemP)s$87dRT>b*CHpk~;(7QH7Pp$#(ERv_1D%jS z-EH8&kNNt$EhMTC=nb^S?I2GMeG9QWY2K>0tO9%1w77Ce%85ev9~BRWhrE0#X|~`- zv3~znQdzFe`sB?ipGj@NX=s@(*Q@nvSA|@Q<+z0SME2B1C$|zk@Nnl3Lw4vYgrD!3 zvFNV1tkz1bc4)<=6HN0w{Z@3R;nzz;T#hN}tl>$=lREx3dsizt>C^>jn9K!B?X(N~ zSe5&usYijt=NRU(o0;d<*E@_>mYYn&39MGcaVdp@j-z-P-dNgUf>(t$kX*+OX?!0` zM%6T$n@-szJ{9cIEVe!GyoTm1BXYX60YOJ1`uP-~KPHSB+6NiAPtFW~^_9{CC+gA&HgN^|tDUAfCUl{ig> z41ED4*@;O@cPj`FYDnHR0_7hB12-iu&g-wlKHPL_c1nHhCc3t-abT%ka{4%0Q^kIq zs=&aZo11P;Sox#l zP&AzBVZbnT@9WY$ns1iJJzWH59V70zQHeRBc#^N)2<=47&K+-UMg4O2{Dw-msWXn> z=vT$^Q9`UK4x{D1I&D*5F5yx8Z(hq!Lkqd2g``q~zYaGbE?k8tv^tIVy|V&wD!osm zFW&lePVp0OUu%bxa@lRulR~OVgLV8?75qjFO(2e4_~)=-xlfDIY|pWzTy&zYj?tCO z!NKW+Y@{>$%cdo__C^Oy@p;#m#pUXi!qd-QyfdMAGDdA?6Zbv>HC3SYjMrWqT9J9E z@zqFE-$r@(Byfdz>!R`G^w;-$>?7iKFyO5m#!Mo8@`%7t+LRLfSXIvAX(&+*dRMAd zNA!GhQbPb*!C|}Z1+QCQlrJSr59H>V`p%vZACH9kmN(KmPIF8neMe_?TFjXrzU!am zA}pfESEK+vj7lHXFG!+5TG0s}#G6h36TW zj^pYC`PcF{GMFeFUR;N=HkU6G_l!s|N|4ioK(j6be?ERNiCMh{gealU{3o~aJ@T>I zIy)l(O8@jLr$t zX!Q~CCTJ-#k#m-k<=Zv3UDw;@*00VY2?IlX`A!Ptn_)_51o0-XXY7sG)&4tNM=bF_ zMs9+HjeT0i3+XIN)P>Z%X%4YZc6sm@_Is~RVIM~n;_rX&72 zax?c!b?}x*gE?vt*}t~_-qURO@r1#Fkt{!_PMAHQ}QYBSMh^2AGaaN>t@%k`QfR1}ERj zR8;nH_Wi48xWtePLL>WmS&V~|zUHkrHY2}KQGM*4a^Pj;K%i#CoxWOIT0XeKm|Y8p zlSZ8%xku(4VDxAJ9i8p004faJSk`dlJUycF_;=6h_!e%+^4KIN)rSUDGZXsNp{=Ff zgZ^o2tcd}D%CdoeNq-iW$HGaKPgp5pu@0Xgs6<}%OnSA=xjb4tDn?zAuP5)PN8%`b z0hlxaH_6VK0>tZb$&zAs=+TT!$ zwn%v)qT3e%v^8X>T8am#%4TyZ{i-5g>!urp71kWOL+rAGZ(Alu9u)$YW6#tWV?@qi zByT}mPoYFT`9UJr@FR`7l|5YDQOHD8toJbKL!ihi+bge-Xo*G@ec4zPDQ`Au4;oed z>gwyb8epp>bu8{NupG1r6zL@h*`Lz|zi>1gAFVrX+QG22S=mk7J8n|d6|2@8pzYoR z@5I1=^`d&s#6|u!_&K1Zjnb#5b`0Ga$+$ITrGN#tpm@jaMg{z2SwVvBw661>In`p) zJQP;0qRF&ZY_@6lDU}8QfbMz>5P_~gC#&hmRIXcc(v&1#i@p(k_~-3O{3&+oG|jcz zpMkm(b+$X;b7%g~%Y4Fe^q_r&gj9!ufvx2el}_hBdkh*DUK~@})S39Cb(KE)z*1pe zXJBs zg=b3e{-n&vb6Z{9v0A3RIq`S;$Nqv1Bmfw~rXa`~17Z=qKJ=K8+{z~DQO*2!jG$Ow z-yr}t2xsNC%D9_kRcYui3Zrq$Ze?OUvlwY;_skXz{};G(G{6F>n6vV#I^u3xkAA z-J2Gat1_oF^dFP^bR@3+__(3X`#nbFmf}2G;oL?%XnsWG!Xs4>5Wo>IFrl6uk)MZ` z@wi40H_4O=OC`IMSb48U6vbobAiGOs%s88()feZwE?}mb!mVpCGAjuOWkI~`XZJ9P zBvdFsQuc^UadVV;qz6kAVNGN0jHEZ75KUeA&|fE>3%KW87&jZGmRIk)oIU??h0m-a z3mV^;5X+~{Sb{##jts5+jWu&|=nhl)H9ocK`jh2sH~j3qbO3WLTF%MtBKbVc{00Gg0kKz9!WeP4#jWNPg3 zLw}QNP0!W#0Ciyi){JldBNuBCx3%n4cd6LsVEH4uXEm8h8hW4FhSN$9cZ;@U_T?y| zT=$Z1q36HcwQv6&L15PQG{e{X{n$$p>^>@{K6Y>)dnsEld#nc#5)cyM6ASP`mYSG?shL7Uj6?Wz811zuo<}iw+5e=uJ+zOa95B2Bahhs WRN`>K`S0=uKwU*gx%#P1#D4%<3Yzl( literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/no_search.xml b/app/src/main/res/drawable/no_search.xml new file mode 100644 index 00000000..26b2b718 --- /dev/null +++ b/app/src/main/res/drawable/no_search.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/src/main/res/drawable/reload_icon.xml b/app/src/main/res/drawable/reload_icon.xml new file mode 100644 index 00000000..62ac46bc --- /dev/null +++ b/app/src/main/res/drawable/reload_icon.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/search_icon.xml b/app/src/main/res/drawable/search_icon.xml new file mode 100644 index 00000000..ead12721 --- /dev/null +++ b/app/src/main/res/drawable/search_icon.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_data_search.xml b/app/src/main/res/layout/activity_data_search.xml new file mode 100644 index 00000000..d45eee2a --- /dev/null +++ b/app/src/main/res/layout/activity_data_search.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_home_map.xml b/app/src/main/res/layout/activity_home_map.xml new file mode 100644 index 00000000..df2b9955 --- /dev/null +++ b/app/src/main/res/layout/activity_home_map.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + \ 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 deleted file mode 100644 index 24d17df2..00000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/activity_map_error.xml b/app/src/main/res/layout/activity_map_error.xml new file mode 100644 index 00000000..c98d32e0 --- /dev/null +++ b/app/src/main/res/layout/activity_map_error.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/map_detail_bottom_sheet.xml b/app/src/main/res/layout/map_detail_bottom_sheet.xml new file mode 100644 index 00000000..a79d2f5d --- /dev/null +++ b/app/src/main/res/layout/map_detail_bottom_sheet.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/recent_search_item.xml b/app/src/main/res/layout/recent_search_item.xml new file mode 100644 index 00000000..606b3977 --- /dev/null +++ b/app/src/main/res/layout/recent_search_item.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/search_data_item.xml b/app/src/main/res/layout/search_data_item.xml new file mode 100644 index 00000000..8dd3c3dd --- /dev/null +++ b/app/src/main/res/layout/search_data_item.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/mycolors.xml b/app/src/main/res/values/mycolors.xml new file mode 100644 index 00000000..42f10415 --- /dev/null +++ b/app/src/main/res/values/mycolors.xml @@ -0,0 +1,5 @@ + + + #00ff0000 + #d8d8d8 + \ No newline at end of file diff --git a/app/src/main/res/values/mystrings.xml b/app/src/main/res/values/mystrings.xml new file mode 100644 index 00000000..421cbb0c --- /dev/null +++ b/app/src/main/res/values/mystrings.xml @@ -0,0 +1,10 @@ + + + 검색어를 입력해 주세요. + 검색 결과가 없습니다. + 누르면 입력중인 검색어가 사라지는 버튼입니다. + 지도의 위치 모양 이미지입니다. + 누르면 최근 검색어가 삭제되는 버튼입니다. + 검색어를 입력해 주세요. + 지도 인증을 실패했습니다.\n다시 시도해 주세요. + \ No newline at end of file From 8c900c21f7c5be3f18f33ff645ff4c9b55cb6fac Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Wed, 24 Jul 2024 01:50:09 +0900 Subject: [PATCH 02/32] docs: Add feature list to README.md 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 73ba54e1..abfdfe15 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ # android-map-refactoring + +### 구현할 기능 목록 +- 데이터베이스를 Room으로 변경 +- 의존성 주입 적용 \ No newline at end of file From 122599d7b243cd69960a7cca9b02dfc50c45e209 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Thu, 25 Jul 2024 23:41:27 +0900 Subject: [PATCH 03/32] feat: Replace SQLite implementation with Room database --- .../kakao/map/activity/DataSearchActivity.kt | 12 ++-- .../kakao/map/adapter/RecentSearchAdapter.kt | 21 ++++-- .../kakao/map/adapter/SearchDataAdapter.kt | 10 ++- .../kakao/map/data/room/SearchHisotryData.kt | 13 ++++ .../kakao/map/data/room/SearchHistoryDao.kt | 25 +++++++ .../map/data/room/SearchHistoryDatabase.kt | 30 ++++++++ .../dataRepository/RecentDataRepository.kt | 71 ------------------- .../dataRepository/SearchHistoryRepository.kt | 58 +++++++++++++++ .../tech/kakao/map/viewModel/DBViewModel.kt | 44 ++++++++++++ .../kakao/map/viewModel/RecentViewModel.kt | 47 ------------ .../viewModel/factory/DBViewModelFactory.kt | 18 +++++ 11 files changed, 217 insertions(+), 132 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/data/room/SearchHisotryData.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDatabase.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt diff --git a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt index d3e05af5..c8ef9a8a 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt @@ -2,7 +2,6 @@ package campus.tech.kakao.map.activity import android.annotation.SuppressLint import android.content.Intent -import android.health.connect.datatypes.ExerciseRoute.Location import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -22,18 +21,21 @@ import campus.tech.kakao.map.listener.SearchAdapterListener import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter import campus.tech.kakao.map.dataContract.LocationDataContract -import campus.tech.kakao.map.viewModel.RecentViewModel +import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.viewModel.SearchViewModel +import campus.tech.kakao.map.viewModel.factory.DBViewModelFactory class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAdapterListener { private lateinit var searchViewModel: SearchViewModel - private lateinit var recentViewModel: RecentViewModel + private lateinit var recentViewModel: DBViewModel private lateinit var editText: EditText private lateinit var resultDataAdapter: SearchDataAdapter private lateinit var searchDataListView: RecyclerView private lateinit var recentSearchListView: RecyclerView private lateinit var noResultNotice: TextView private lateinit var deleteBtn: ImageButton + private lateinit var dbRepo: SearchHistoryRepository @SuppressLint("MissingInflatedId") @@ -50,7 +52,9 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda //ViewModel 생성 searchViewModel = ViewModelProvider(this)[SearchViewModel::class.java] - recentViewModel = ViewModelProvider(this)[RecentViewModel::class.java] + dbRepo = SearchHistoryRepository(this) + recentViewModel = + ViewModelProvider(this, DBViewModelFactory(dbRepo))[DBViewModel::class.java] //검색 결과 목록 세로 스크롤 설정 searchDataListView.layoutManager = LinearLayoutManager(this) diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt index ac2572fa..f7cc5de9 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt @@ -1,19 +1,22 @@ package campus.tech.kakao.map.adapter +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageButton import android.widget.TextView +import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView -import campus.tech.kakao.map.data.RecentSearchData import campus.tech.kakao.map.R +import campus.tech.kakao.map.data.room.SearchHistoryData import campus.tech.kakao.map.listener.RecentAdapterListener -import campus.tech.kakao.map.viewModel.RecentViewModel +import campus.tech.kakao.map.viewModel.DBViewModel +import kotlinx.coroutines.launch class RecentSearchAdapter( - private val recentDataList: List, - private val viewModel: RecentViewModel, + private val searchHistoryDataList: List, + private val viewModel: DBViewModel, private val adapterListener: RecentAdapterListener ) : RecyclerView.Adapter() { @@ -28,14 +31,18 @@ class RecentSearchAdapter( return RecentViewHolder(view) } - override fun getItemCount(): Int = recentDataList.count() + override fun getItemCount(): Int = searchHistoryDataList.count() override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val item = recentDataList[position] + val item = searchHistoryDataList[position] val viewHolder = holder as RecentViewHolder viewHolder.name.text = item.name + viewHolder.deleteBtn.setOnClickListener { - viewModel.deleteRecentData(item.name, item.address) + Log.d("yeong","Adapter: delete 버튼 누름") + viewModel.viewModelScope.launch { + viewModel.deleteRecentData(item.name, item.address, item.searchTime) + } } viewHolder.name.setOnClickListener { diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt index 254808c3..e7a5b17d 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt @@ -4,15 +4,17 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R import campus.tech.kakao.map.listener.SearchAdapterListener -import campus.tech.kakao.map.viewModel.RecentViewModel +import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.retrofit.Document +import kotlinx.coroutines.launch class SearchDataAdapter( private var items: List, - private val recentViewModel: RecentViewModel, + private val recentViewModel: DBViewModel, private var adapterListener: SearchAdapterListener ) : RecyclerView.Adapter() { @@ -43,7 +45,9 @@ class SearchDataAdapter( } holder.itemView.setOnClickListener { val searchTime = System.currentTimeMillis() - recentViewModel.addRecentData(item.name, item.address, searchTime) + recentViewModel.viewModelScope.launch { + recentViewModel.addRecentSearchItem(item.name, item.address, searchTime) + } adapterListener.displaySearchLocation( item.name, item.address, diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHisotryData.kt b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHisotryData.kt new file mode 100644 index 00000000..96616cd7 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHisotryData.kt @@ -0,0 +1,13 @@ +package campus.tech.kakao.map.data.room + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "searchHistory") +data class SearchHistoryData( + @PrimaryKey(autoGenerate = true) val id: Int = 0, + @ColumnInfo val name: String, + @ColumnInfo val address: String, + @ColumnInfo val searchTime: Long +) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt new file mode 100644 index 00000000..6bdc022a --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt @@ -0,0 +1,25 @@ +package campus.tech.kakao.map.data.room + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query + +@Dao +interface SearchHistoryDao { + @Query("SELECT * FROM searchHistory ORDER BY searchTime DESC") + suspend fun getSearchHistory(): List + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insertSearchHistory(vararg searchHistory: SearchHistoryData) + + @Query("DELETE FROM searchHistory WHERE name = :name AND address = :address") + suspend fun deleteSearchItem(name: String, address: String) + + @Query("UPDATE searchHistory SET searchTime = :newTime WHERE name = :name AND address = :address") + suspend fun updateSearchTime(name: String, address: String, newTime: Long) + + @Query("SELECT * FROM searchHistory WHERE name = :name AND address = :address") + suspend fun findSearchItem(name: String, address: String): SearchHistoryData? +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDatabase.kt b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDatabase.kt new file mode 100644 index 00000000..05c4ac75 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDatabase.kt @@ -0,0 +1,30 @@ +package campus.tech.kakao.map.data.room + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase + +@Database(entities = [SearchHistoryData::class], version = 1, exportSchema = false) +abstract class SearchHistoryDatabase : RoomDatabase() { + + abstract fun searchHistoryDao(): SearchHistoryDao + + companion object { + @Volatile + private var INSTANCE: SearchHistoryDatabase? = null + + fun getDatabase(context: Context): SearchHistoryDatabase { + return INSTANCE ?: synchronized(this) { + val instance = Room.databaseBuilder( + context.applicationContext, + SearchHistoryDatabase::class.java, + "searchHistory_database" + ).fallbackToDestructiveMigration() + .build() + INSTANCE = instance + return instance + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt deleted file mode 100644 index 97d7279a..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt +++ /dev/null @@ -1,71 +0,0 @@ -package campus.tech.kakao.map.dataRepository - -import android.content.ContentValues -import android.content.Context -import android.database.Cursor -import campus.tech.kakao.map.dBHelper.RecentDBHelper -import campus.tech.kakao.map.dataContract.RecentDataContract -import campus.tech.kakao.map.data.RecentSearchData - -class RecentDataRepository(context: Context) { - private val db: RecentDBHelper = RecentDBHelper(context) - private val wDb = db.writableDatabase - private val rDb = db.readableDatabase - - fun insertSearchData(data: RecentSearchData) { - val cv = ContentValues().apply { - put(RecentDataContract.TABLE_COLUMN_NAME, data.name) - put(RecentDataContract.TABLE_COLUMN_ADDRESS, data.address) - put(RecentDataContract.TABLE_COLUMN_TIME, data.time) - } - wDb.insert(RecentDataContract.TABLE_NAME, null, cv) - } - - fun getRecentSearchDataList(): List { - val cursor: Cursor = rDb.query( - RecentDataContract.TABLE_NAME, - null, - null, - null, - null, - null, - "${RecentDataContract.TABLE_COLUMN_TIME} DESC" - ) - val recentDataList = mutableListOf() - - while (cursor.moveToNext()) { - val name = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_NAME)) - val address = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_ADDRESS)) - val time = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_TIME)) - - recentDataList.add(RecentSearchData(name, address, time.toLong())) - } - cursor.close() - - return recentDataList - } - - fun deleteSearchData(data: String, address: String) { - wDb.delete( - RecentDataContract.TABLE_NAME, - "${RecentDataContract.TABLE_COLUMN_NAME} = ? AND ${RecentDataContract.TABLE_COLUMN_ADDRESS} = ?", - arrayOf(data, address) - ) - } - - fun updateTime(data: RecentSearchData) { - val cv = ContentValues().apply { - put(RecentDataContract.TABLE_COLUMN_TIME, data.time) - } - - wDb.update( - RecentDataContract.TABLE_NAME, - cv, - "${RecentDataContract.TABLE_COLUMN_NAME} = ?", - arrayOf(data.name) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt new file mode 100644 index 00000000..5fd5b2dc --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt @@ -0,0 +1,58 @@ +package campus.tech.kakao.map.dataRepository + +import android.content.Context +import android.util.Log +import campus.tech.kakao.map.data.room.SearchHistoryDao +import campus.tech.kakao.map.data.room.SearchHistoryData +import campus.tech.kakao.map.data.room.SearchHistoryDatabase +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class SearchHistoryRepository(context: Context) { + + private val searchHistoryDao: SearchHistoryDao = + SearchHistoryDatabase.getDatabase(context).searchHistoryDao() + + suspend fun getSearchHistory(): List { + return withContext(Dispatchers.IO) { + searchHistoryDao.getSearchHistory() + } + } + + suspend fun insertSearchData(name: String, address: String, time: Long) { + withContext(Dispatchers.IO) { + val data = mappingData(name, address, time) + searchHistoryDao.insertSearchHistory(data) + } + } + + suspend fun deleteSearchData(name: String, address: String, time: Long) { + withContext(Dispatchers.IO) { + Log.d("yeong","Repository: 여기 까지 옴") + val item = searchHistoryDao.findSearchItem(name, address) + if (item != null) { + searchHistoryDao.deleteSearchItem(name, address) + } + } + } + + suspend fun updateTime(name: String, address: String, time: Long) { + withContext(Dispatchers.IO) { + searchHistoryDao.updateSearchTime(name, address, time) + } + } + + suspend fun findSearchItem(name: String, address: String): SearchHistoryData? { + return withContext(Dispatchers.IO) { + searchHistoryDao.findSearchItem(name, address) + } + } + + private fun mappingData(name: String, address: String, time: Long): SearchHistoryData { + return SearchHistoryData( + name = name, + address = address, + searchTime = time + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt new file mode 100644 index 00000000..22f6b8f7 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt @@ -0,0 +1,44 @@ +package campus.tech.kakao.map.viewModel + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import campus.tech.kakao.map.data.room.SearchHistoryData +import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import kotlinx.coroutines.launch + +class DBViewModel(private val searchHistoryRepo: SearchHistoryRepository) : ViewModel() { + + private val _searchHistoryDataList = MutableLiveData>() + private val searchHistoryDataList: LiveData> = _searchHistoryDataList + + init { + viewModelScope.launch { + _searchHistoryDataList.value = searchHistoryRepo.getSearchHistory() + } + } + + suspend fun addRecentSearchItem(name: String, address: String, time: Long) { + viewModelScope.launch { + val exitData = searchHistoryRepo.findSearchItem(name, address) + + if (exitData != null) { + searchHistoryRepo.updateTime(name, address, time) + } else { + searchHistoryRepo.insertSearchData(name, address, time) + } + } + } + + fun getRecentDataLiveData(): LiveData> { + return searchHistoryDataList + } + + suspend fun deleteRecentData(data: String, address: String, time: Long) { + Log.d("yeong","DBViewModel: 여기까지 옴") + searchHistoryRepo.deleteSearchData(data, address, time) + _searchHistoryDataList.value = searchHistoryRepo.getSearchHistory() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt deleted file mode 100644 index 0118a719..00000000 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt +++ /dev/null @@ -1,47 +0,0 @@ -package campus.tech.kakao.map.viewModel - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import campus.tech.kakao.map.dataRepository.RecentDataRepository -import campus.tech.kakao.map.data.RecentSearchData - -class RecentViewModel(application: Application) : AndroidViewModel(application) { - private val repository: RecentDataRepository = RecentDataRepository(application) - - private val _recentDataList = MutableLiveData>() - - init { - _recentDataList.value = repository.getRecentSearchDataList() - } - - fun addRecentData(data: String, address: String, time: Long) { - val currentList = _recentDataList.value.orEmpty().toMutableList() - val selectData = RecentSearchData(data, address, time) - - if (checkExist(currentList, selectData)) { - repository.insertSearchData(selectData) - } else { - repository.updateTime(selectData) - } - _recentDataList.value = repository.getRecentSearchDataList() - } - - //DB에 데이터 추가 전 중복 검사 (현재 DB에 없으면 true) - private fun checkExist( - currentList: MutableList, - data: RecentSearchData - ): Boolean { - return !currentList.any { it.name == data.name && it.address == data.address } - } - - fun getRecentDataLiveData(): LiveData> { - return _recentDataList - } - - fun deleteRecentData(data: String, address: String) { - repository.deleteSearchData(data, address) - _recentDataList.value = repository.getRecentSearchDataList() - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt new file mode 100644 index 00000000..259e2525 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt @@ -0,0 +1,18 @@ +package campus.tech.kakao.map.viewModel.factory + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import campus.tech.kakao.map.viewModel.DBViewModel +import java.lang.IllegalArgumentException + +class DBViewModelFactory(repository: SearchHistoryRepository) : ViewModelProvider.Factory { + private val dbRepo = repository + + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(DBViewModel::class.java)) { + return DBViewModel(dbRepo) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file From 31f7ad8569a8c9bc8fecf40c2c433d1bd37d32ed Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Thu, 25 Jul 2024 23:42:51 +0900 Subject: [PATCH 04/32] refactor: Remove SQLite-related files after Room migration --- .../tech/kakao/map/dBHelper/RecentDBHelper.kt | 28 ------------------- .../tech/kakao/map/data/RecentSearchData.kt | 4 --- .../map/dataContract/RecentDataContract.kt | 10 ------- 3 files changed, 42 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt diff --git a/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt b/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt deleted file mode 100644 index 744b568f..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt +++ /dev/null @@ -1,28 +0,0 @@ -package campus.tech.kakao.map.dBHelper - -import android.content.Context -import android.database.sqlite.SQLiteDatabase -import android.database.sqlite.SQLiteOpenHelper -import campus.tech.kakao.map.dataContract.RecentDataContract - -//version 2: DB에 time 컬럼을 추가함 -//version 3" DB에 address 컬럼을 추가함 -class RecentDBHelper(context: Context) : SQLiteOpenHelper(context, "RecentData.db", null, 3) { - override fun onCreate(db: SQLiteDatabase?) { - createRecentDataTable(db) - } - - override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { - db?.execSQL("DROP TABLE IF EXISTS ${RecentDataContract.TABLE_NAME}") - createRecentDataTable(db) - } - - private fun createRecentDataTable(db: SQLiteDatabase?) { - db?.execSQL( - "CREATE TABLE ${RecentDataContract.TABLE_NAME} (" + - "${RecentDataContract.TABLE_COLUMN_NAME} varchar(30) NOT NULL, " + - "${RecentDataContract.TABLE_COLUMN_ADDRESS} varchar(50) NOT NULL, " + - "${RecentDataContract.TABLE_COLUMN_TIME} integer NOT NULL);" - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt b/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt deleted file mode 100644 index 31bddf16..00000000 --- a/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt +++ /dev/null @@ -1,4 +0,0 @@ -package campus.tech.kakao.map.data - - -data class RecentSearchData(val name: String, val address: String, val time: Long) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt b/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt deleted file mode 100644 index 352f38a9..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt +++ /dev/null @@ -1,10 +0,0 @@ -package campus.tech.kakao.map.dataContract - -import android.provider.BaseColumns - -object RecentDataContract : BaseColumns { - const val TABLE_NAME = "RecentData" - const val TABLE_COLUMN_NAME = "name" - const val TABLE_COLUMN_ADDRESS = "address" - const val TABLE_COLUMN_TIME = "recentSearchTime" -} \ No newline at end of file From 1ab355ed989a4e257226978223d171ca69a094a6 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 10:13:56 +0900 Subject: [PATCH 05/32] docs: Update README --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index abfdfe15..c0a77f01 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # android-map-refactoring ### 구현할 기능 목록 +[step1] - 데이터베이스를 Room으로 변경 -- 의존성 주입 적용 \ No newline at end of file +- 의존성 주입 적용 +[step2] +- MVVM 아키텍처 패턴 적용 + - DataBinding, LiveData 사용 +- 비동기 처리를 Coroutine으로 변경 \ No newline at end of file From c951666a7038990c9df414613d8103e6d4ba6132 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 10:15:19 +0900 Subject: [PATCH 06/32] docs: Fix line break issues in README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c0a77f01..2d22c29c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ [step1] - 데이터베이스를 Room으로 변경 - 의존성 주입 적용 + + [step2] - MVVM 아키텍처 패턴 적용 - DataBinding, LiveData 사용 -- 비동기 처리를 Coroutine으로 변경 \ No newline at end of file +- 비동기 처리를 Coroutine으로 변경 From b9171d4c1c883d696e32798dfdaf9f0cadf9aa99 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 11:41:52 +0900 Subject: [PATCH 07/32] refactor: Implement MapErrorViewModel with LiveData and data binding --- .../tech/kakao/map/MapErrorActivityTest.kt | 33 ------ .../java/campus/tech/kakao/map/Application.kt | 2 + .../kakao/map/activity/HomeMapActivity.kt | 4 +- .../kakao/map/activity/MapErrorActivity.kt | 15 --- .../kakao/map/viewModel/MapErrorViewModel.kt | 14 +++ .../main/res/layout/activity_map_error.xml | 100 ++++++++++-------- .../tech/kakao/map/MapErrorViewModelTest.kt | 36 +++++++ 7 files changed, 110 insertions(+), 94 deletions(-) delete mode 100644 app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt create mode 100644 app/src/test/java/campus/tech/kakao/map/MapErrorViewModelTest.kt diff --git a/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt deleted file mode 100644 index b6ce747d..00000000 --- a/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt +++ /dev/null @@ -1,33 +0,0 @@ -package campus.tech.kakao.map - -import android.content.Intent -import androidx.test.core.app.ApplicationProvider -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.ext.junit.rules.ActivityScenarioRule -import campus.tech.kakao.map.activity.HomeMapActivity -import campus.tech.kakao.map.activity.MapErrorActivity -import org.junit.Rule -import org.junit.Test - - -class MapErrorActivityTest { - @get:Rule - val activityRule : ActivityScenarioRule = - ActivityScenarioRule( - Intent( - ApplicationProvider.getApplicationContext(), - MapErrorActivity::class.java - ).apply { - putExtra("errorMessage","java.lang.Exception:401") - } - ) - - @Test - fun onMapError_예외설명_에러화면에_나타남() { - onView(withId(R.id.error_detail)) - .check(matches(withText("401"))) - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/Application.kt b/app/src/main/java/campus/tech/kakao/map/Application.kt index dbd2084a..ea681f61 100644 --- a/app/src/main/java/campus/tech/kakao/map/Application.kt +++ b/app/src/main/java/campus/tech/kakao/map/Application.kt @@ -2,7 +2,9 @@ package campus.tech.kakao.map import android.app.Application import com.kakao.vectormap.KakaoMapSdk +import dagger.hilt.android.HiltAndroidApp +@HiltAndroidApp class Application : Application() { override fun onCreate(){ super.onCreate() diff --git a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt index 8c63c015..18c7c11f 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt @@ -14,6 +14,7 @@ import campus.tech.kakao.map.MapViewModelFactory import campus.tech.kakao.map.PreferenceRepository import campus.tech.kakao.map.R import campus.tech.kakao.map.dataContract.LocationDataContract +import campus.tech.kakao.map.viewModel.MapErrorViewModel import campus.tech.kakao.map.viewModel.MapViewModel import com.google.android.material.bottomsheet.BottomSheetBehavior import com.kakao.vectormap.KakaoMap @@ -55,6 +56,7 @@ class HomeMapActivity : AppCompatActivity() { placeAddressTextView = findViewById(R.id.placeAddress) bottomBehavior = BottomSheetBehavior.from(bottomSheet) + val mapErrorViewModel: MapErrorViewModel = ViewModelProvider(this)[MapErrorViewModel::class.java] val intentError = Intent(this, MapErrorActivity::class.java) //KaKao Map UI에 띄우기 @@ -63,7 +65,7 @@ class HomeMapActivity : AppCompatActivity() { } override fun onMapError(p0: Exception?) { - intentError.putExtra("errorMessage", p0.toString()) + mapErrorViewModel.setErrorDetail(p0.toString()) startActivity(intentError) } diff --git a/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt index 8e981742..7a11b504 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt @@ -1,14 +1,9 @@ package campus.tech.kakao.map.activity import android.os.Bundle -import android.util.Log -import android.widget.TextView -import android.window.OnBackInvokedDispatcher import androidx.activity.OnBackPressedCallback import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat import campus.tech.kakao.map.R class MapErrorActivity : AppCompatActivity() { @@ -16,16 +11,6 @@ class MapErrorActivity : AppCompatActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_map_error) - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets - } - - //전달 받은 에러 메세지에서 임의로 내용 일부 추출 - val errorMessage = intent.getStringExtra("errorMessage")?.substringAfterLast(":") - val errorTextView = findViewById(R.id.error_detail) - errorTextView.text = errorMessage onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt new file mode 100644 index 00000000..cd2532df --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt @@ -0,0 +1,14 @@ +package campus.tech.kakao.map.viewModel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class MapErrorViewModel: ViewModel() { + private val _errorMessage = MutableLiveData() + val errorMessage: LiveData get() = _errorMessage + + fun setErrorDetail(errorMessage: String){ + _errorMessage.value = errorMessage.substringAfterLast(":") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map_error.xml b/app/src/main/res/layout/activity_map_error.xml index c98d32e0..5d8f06a3 100644 --- a/app/src/main/res/layout/activity_map_error.xml +++ b/app/src/main/res/layout/activity_map_error.xml @@ -1,52 +1,62 @@ - + xmlns:tools="http://schemas.android.com/tools"> - + + + + - + - + - + - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/app/src/test/java/campus/tech/kakao/map/MapErrorViewModelTest.kt b/app/src/test/java/campus/tech/kakao/map/MapErrorViewModelTest.kt new file mode 100644 index 00000000..d84c934e --- /dev/null +++ b/app/src/test/java/campus/tech/kakao/map/MapErrorViewModelTest.kt @@ -0,0 +1,36 @@ +package campus.tech.kakao.map + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import campus.tech.kakao.map.viewModel.MapErrorViewModel +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations + +class MapErrorViewModelTest { + @get: Rule + val instantExecutorRule = InstantTaskExecutorRule() + + private lateinit var viewModel: MapErrorViewModel + + @Mock + private lateinit var errorMessageObserver: Observer + + @Before + fun setUp(){ + MockitoAnnotations.initMocks(this) + viewModel = MapErrorViewModel() + viewModel.errorMessage.observeForever(errorMessageObserver) + } + + @Test + fun 오류메시지가_정상적으로_설정됨() = runTest{ + val error = "java.lang.Exception:401" + viewModel.setErrorDetail(error) + Mockito.verify(errorMessageObserver).onChanged("401") + } +} \ No newline at end of file From 86c41a563ea375a53fbc41bf1b2ae30140a0cbcf Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 11:48:00 +0900 Subject: [PATCH 08/32] rename: Reorganize project folder structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기능 수정 없음 --- .../campus/tech/kakao/map/activity/DataSearchActivity.kt | 4 ++-- .../java/campus/tech/kakao/map/activity/HomeMapActivity.kt | 6 +++--- .../map/{dataContract => data}/LocationDataContract.kt | 2 +- .../tech/kakao/map/{ => repository}/PreferenceRepository.kt | 2 +- .../{dataRepository => repository}/SearchDataRepository.kt | 2 +- .../SearchHistoryRepository.kt | 2 +- .../java/campus/tech/kakao/map/viewModel/DBViewModel.kt | 2 +- .../java/campus/tech/kakao/map/viewModel/MapViewModel.kt | 2 +- .../java/campus/tech/kakao/map/viewModel/SearchViewModel.kt | 2 +- .../tech/kakao/map/viewModel/factory/DBViewModelFactory.kt | 2 +- .../map/{ => viewModel/factory}/MapViewModelFactory.kt | 3 ++- 11 files changed, 15 insertions(+), 14 deletions(-) rename app/src/main/java/campus/tech/kakao/map/{dataContract => data}/LocationDataContract.kt (82%) rename app/src/main/java/campus/tech/kakao/map/{ => repository}/PreferenceRepository.kt (92%) rename app/src/main/java/campus/tech/kakao/map/{dataRepository => repository}/SearchDataRepository.kt (97%) rename app/src/main/java/campus/tech/kakao/map/{dataRepository => repository}/SearchHistoryRepository.kt (97%) rename app/src/main/java/campus/tech/kakao/map/{ => viewModel/factory}/MapViewModelFactory.kt (84%) diff --git a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt index c8ef9a8a..cbc618c6 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt @@ -20,8 +20,8 @@ import campus.tech.kakao.map.listener.RecentAdapterListener import campus.tech.kakao.map.listener.SearchAdapterListener import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter -import campus.tech.kakao.map.dataContract.LocationDataContract -import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import campus.tech.kakao.map.data.LocationDataContract +import campus.tech.kakao.map.repository.SearchHistoryRepository import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.viewModel.SearchViewModel import campus.tech.kakao.map.viewModel.factory.DBViewModelFactory diff --git a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt index 18c7c11f..b86c4081 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt @@ -10,10 +10,10 @@ import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.MapViewModelFactory -import campus.tech.kakao.map.PreferenceRepository +import campus.tech.kakao.map.viewModel.factory.MapViewModelFactory +import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.R -import campus.tech.kakao.map.dataContract.LocationDataContract +import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.viewModel.MapErrorViewModel import campus.tech.kakao.map.viewModel.MapViewModel import com.google.android.material.bottomsheet.BottomSheetBehavior diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt b/app/src/main/java/campus/tech/kakao/map/data/LocationDataContract.kt similarity index 82% rename from app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt rename to app/src/main/java/campus/tech/kakao/map/data/LocationDataContract.kt index 1fc74189..07127117 100644 --- a/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt +++ b/app/src/main/java/campus/tech/kakao/map/data/LocationDataContract.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.dataContract +package campus.tech.kakao.map.data object LocationDataContract { const val LOCATION_NAME = "name" diff --git a/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt similarity index 92% rename from app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt rename to app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt index fcb845bd..23595143 100644 --- a/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map +package campus.tech.kakao.map.repository import android.content.Context import android.content.SharedPreferences diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt similarity index 97% rename from app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt rename to app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt index acab6899..02883277 100644 --- a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.dataRepository +package campus.tech.kakao.map.repository import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt similarity index 97% rename from app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt rename to app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt index 5fd5b2dc..5043473e 100644 --- a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchHistoryRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.dataRepository +package campus.tech.kakao.map.repository import android.content.Context import android.util.Log diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt index 22f6b8f7..eca7df7e 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import campus.tech.kakao.map.data.room.SearchHistoryData -import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import campus.tech.kakao.map.repository.SearchHistoryRepository import kotlinx.coroutines.launch class DBViewModel(private val searchHistoryRepo: SearchHistoryRepository) : ViewModel() { diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt index c9c3a35f..fbdfaf96 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt @@ -1,7 +1,7 @@ package campus.tech.kakao.map.viewModel import androidx.lifecycle.ViewModel -import campus.tech.kakao.map.PreferenceRepository +import campus.tech.kakao.map.repository.PreferenceRepository class MapViewModel(repository: PreferenceRepository) : ViewModel() { diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt index de93474c..73f9ce34 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt @@ -2,7 +2,7 @@ package campus.tech.kakao.map.viewModel import android.app.Application import androidx.lifecycle.AndroidViewModel -import campus.tech.kakao.map.dataRepository.SearchDataRepository +import campus.tech.kakao.map.repository.SearchDataRepository class SearchViewModel(application: Application) : AndroidViewModel(application) { private val repository: SearchDataRepository = SearchDataRepository() diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt index 259e2525..7559a578 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt @@ -2,7 +2,7 @@ package campus.tech.kakao.map.viewModel.factory import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.dataRepository.SearchHistoryRepository +import campus.tech.kakao.map.repository.SearchHistoryRepository import campus.tech.kakao.map.viewModel.DBViewModel import java.lang.IllegalArgumentException diff --git a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt similarity index 84% rename from app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt rename to app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt index 6a3098e6..d40bb5f7 100644 --- a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt @@ -1,7 +1,8 @@ -package campus.tech.kakao.map +package campus.tech.kakao.map.viewModel.factory import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.viewModel.MapViewModel import java.lang.IllegalArgumentException From 94168576edb6cb19c2ef134e79d90a3f908c3fd5 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 16:48:36 +0900 Subject: [PATCH 09/32] refactor: Refactor DataSearchActivity to use DataBinding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DataSearchActivity에서 databinding 사용 - SearchViewModel가 LiveData 관리하도록 코드 수정 --- .../kakao/map/activity/DataSearchActivity.kt | 110 +++++++-------- .../kakao/map/adapter/RecentSearchAdapter.kt | 10 +- .../kakao/map/adapter/SearchDataAdapter.kt | 2 +- .../listener/RecentAdapterListener.kt | 2 +- .../listener/SearchAdapterListener.kt | 2 +- ...epository.kt => SearchResultRepository.kt} | 16 +-- .../kakao/map/viewModel/SearchViewModel.kt | 25 ++-- .../factory/SearchViewModelFactory.kt | 15 ++ .../main/res/layout/activity_data_search.xml | 132 ++++++++++-------- 9 files changed, 162 insertions(+), 152 deletions(-) rename app/src/main/java/campus/tech/kakao/map/{ => adapter}/listener/RecentAdapterListener.kt (61%) rename app/src/main/java/campus/tech/kakao/map/{ => adapter}/listener/SearchAdapterListener.kt (74%) rename app/src/main/java/campus/tech/kakao/map/repository/{SearchDataRepository.kt => SearchResultRepository.kt} (70%) create mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt diff --git a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt index cbc618c6..492b667b 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt @@ -1,110 +1,98 @@ package campus.tech.kakao.map.activity -import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.View -import android.widget.EditText -import android.widget.ImageButton -import android.widget.TextView -import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity +import androidx.databinding.DataBindingUtil import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R -import campus.tech.kakao.map.listener.RecentAdapterListener -import campus.tech.kakao.map.listener.SearchAdapterListener +import campus.tech.kakao.map.adapter.listener.RecentAdapterListener +import campus.tech.kakao.map.adapter.listener.SearchAdapterListener import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter import campus.tech.kakao.map.data.LocationDataContract +import campus.tech.kakao.map.databinding.ActivityDataSearchBinding import campus.tech.kakao.map.repository.SearchHistoryRepository +import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.viewModel.SearchViewModel import campus.tech.kakao.map.viewModel.factory.DBViewModelFactory +import campus.tech.kakao.map.viewModel.factory.SearchViewModelFactory class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAdapterListener { - private lateinit var searchViewModel: SearchViewModel - private lateinit var recentViewModel: DBViewModel - private lateinit var editText: EditText - private lateinit var resultDataAdapter: SearchDataAdapter - private lateinit var searchDataListView: RecyclerView - private lateinit var recentSearchListView: RecyclerView - private lateinit var noResultNotice: TextView - private lateinit var deleteBtn: ImageButton - private lateinit var dbRepo: SearchHistoryRepository - - - @SuppressLint("MissingInflatedId") + private lateinit var searchResultRepo: SearchResultRepository //검색 결과 관리 + private lateinit var dbRepo: SearchHistoryRepository //최근 검색어 데이터 관리 + private lateinit var searchViewModel: SearchViewModel //검색 결과 관리 + private lateinit var recentViewModel: DBViewModel //최근 검색어 관리 + private lateinit var searchResultDataAdapter: SearchDataAdapter //검색 결과 표시 위함 + private lateinit var binding: ActivityDataSearchBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_data_search) - - //View 초기화 - searchDataListView = findViewById(R.id.searchResulListView) - editText = findViewById(R.id.searchBar) - noResultNotice = findViewById(R.id.noResult) - deleteBtn = findViewById(R.id.deleteInput) - recentSearchListView = findViewById(R.id.recentSearchListView) + binding = DataBindingUtil.setContentView(this, R.layout.activity_data_search) //ViewModel 생성 - searchViewModel = ViewModelProvider(this)[SearchViewModel::class.java] + searchResultRepo = SearchResultRepository() + searchViewModel = ViewModelProvider( + this, + SearchViewModelFactory(searchResultRepo) + )[SearchViewModel::class.java] + dbRepo = SearchHistoryRepository(this) recentViewModel = ViewModelProvider(this, DBViewModelFactory(dbRepo))[DBViewModel::class.java] - //검색 결과 목록 세로 스크롤 설정 - searchDataListView.layoutManager = LinearLayoutManager(this) - //최근 검색어 목록 가로 스크롤 설정 - recentSearchListView.layoutManager = + //RecyclerView Layout 매니저 설정 (스크롤 방향 설정) + binding.searchResulListView.layoutManager = LinearLayoutManager(this) + binding.recentSearchListView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) - //어뎁터 초기화 - resultDataAdapter = SearchDataAdapter(emptyList(), recentViewModel, this) - searchDataListView.adapter = resultDataAdapter + //Adapter 초기화 + // Adapter 초기화 + searchResultDataAdapter = SearchDataAdapter(emptyList(), recentViewModel, this) + binding.searchResulListView.adapter = searchResultDataAdapter + binding.recentSearchListView.adapter = + RecentSearchAdapter(emptyList(), recentViewModel, this) - resetButtonListener() - setTextWatcher() - - recentViewModel.getRecentDataLiveData().observe(this, Observer { recentData -> - recentSearchListView.adapter = RecentSearchAdapter(recentData, recentViewModel, this) - }) + resetButtonListener() //x버튼 눌러 검색 입력 필드 내용 삭제 + setTextWatcher() //검색 입력 필드 텍스트 변경 리스너 - searchViewModel.searchResults.observe(this, Observer { documentsList -> + //검색 결과 데이터 관찰 -> searchResultAdapter 데이터 넘기기 + searchViewModel.getSearchDataLiveData().observe(this, Observer { documentsList -> if (documentsList.isNotEmpty()) { - noResultNotice.visibility = View.GONE - resultDataAdapter.updateData(documentsList) + binding.noResult.visibility = View.GONE + searchResultDataAdapter.updateData(documentsList) } else { - noResultNotice.visibility = View.VISIBLE - resultDataAdapter.updateData(emptyList()) + binding.noResult.visibility = View.VISIBLE + searchResultDataAdapter.updateData(emptyList()) } }) - val onBackPressedCallback = object : OnBackPressedCallback(true) { - override fun handleOnBackPressed() { - val intent = Intent(this@DataSearchActivity, HomeMapActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - startActivity(intent) - } - } - this.onBackPressedDispatcher.addCallback(this, onBackPressedCallback) + //검색 history 데이터 관찰 + recentViewModel.getRecentDataLiveData().observe(this, Observer { recentData -> + binding.recentSearchListView.adapter = + RecentSearchAdapter(recentData, recentViewModel, this) + }) } private fun setTextWatcher() { - editText.addTextChangedListener(object : TextWatcher { + binding.searchBar.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 searchInput = editText.text.trim().toString() + val searchInput = binding.searchBar.text.trim().toString() if (searchInput.isNotEmpty()) { searchViewModel.loadResultData(searchInput) } else { - noResultNotice.visibility = View.VISIBLE - resultDataAdapter.updateData(emptyList()) + binding.noResult.visibility = View.VISIBLE + searchResultDataAdapter.updateData(emptyList()) } } @@ -114,14 +102,14 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda } private fun resetButtonListener() { - deleteBtn.setOnClickListener { - editText.text.clear() + binding.deleteInput.setOnClickListener { + binding.searchBar.text.clear() } } //클릭한 검색어가 자동으로 입력되는 기능 구현 override fun autoSearch(searchData: String) { - editText.setText(searchData) + binding.searchBar.setText(searchData) } override fun displaySearchLocation( diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt index f7cc5de9..3e783164 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt @@ -1,6 +1,5 @@ package campus.tech.kakao.map.adapter -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -10,13 +9,13 @@ import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R import campus.tech.kakao.map.data.room.SearchHistoryData -import campus.tech.kakao.map.listener.RecentAdapterListener +import campus.tech.kakao.map.adapter.listener.RecentAdapterListener import campus.tech.kakao.map.viewModel.DBViewModel import kotlinx.coroutines.launch class RecentSearchAdapter( private val searchHistoryDataList: List, - private val viewModel: DBViewModel, + private val dbViewModel: DBViewModel, private val adapterListener: RecentAdapterListener ) : RecyclerView.Adapter() { @@ -39,9 +38,8 @@ class RecentSearchAdapter( viewHolder.name.text = item.name viewHolder.deleteBtn.setOnClickListener { - Log.d("yeong","Adapter: delete 버튼 누름") - viewModel.viewModelScope.launch { - viewModel.deleteRecentData(item.name, item.address, item.searchTime) + dbViewModel.viewModelScope.launch { + dbViewModel.deleteRecentData(item.name, item.address, item.searchTime) } } diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt index e7a5b17d..f7fc3dc3 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt @@ -7,7 +7,7 @@ import android.widget.TextView import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R -import campus.tech.kakao.map.listener.SearchAdapterListener +import campus.tech.kakao.map.adapter.listener.SearchAdapterListener import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.retrofit.Document import kotlinx.coroutines.launch diff --git a/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/adapter/listener/RecentAdapterListener.kt similarity index 61% rename from app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt rename to app/src/main/java/campus/tech/kakao/map/adapter/listener/RecentAdapterListener.kt index 05716243..bfc8a193 100644 --- a/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/listener/RecentAdapterListener.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.listener +package campus.tech.kakao.map.adapter.listener interface RecentAdapterListener { fun autoSearch(searchData: String) diff --git a/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/adapter/listener/SearchAdapterListener.kt similarity index 74% rename from app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt rename to app/src/main/java/campus/tech/kakao/map/adapter/listener/SearchAdapterListener.kt index 11481426..70d54690 100644 --- a/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/listener/SearchAdapterListener.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.listener +package campus.tech.kakao.map.adapter.listener interface SearchAdapterListener { fun displaySearchLocation(name: String, address: String, latitude: String, longitude: String) diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt similarity index 70% rename from app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt rename to app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt index 02883277..091d274c 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchDataRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt @@ -1,18 +1,13 @@ package campus.tech.kakao.map.repository -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import campus.tech.kakao.map.retrofit.CategoryData import campus.tech.kakao.map.retrofit.Document import campus.tech.kakao.map.retrofit.RetrofitAPI.getResultFromAPI -class SearchDataRepository(){ - private val _searchDataList = MutableLiveData>() - val searchResults: LiveData> - get() = _searchDataList +class SearchResultRepository { - //검색 결과 가공 후 LiveData에 저장 - fun loadResultMapData(data: String) { + //검색 결과 가공 + fun loadResultMapData(data: String, callback: (List) -> Unit) { getResultFromAPI(data) { response -> if (response.isSuccessful) { val body = response.body() @@ -20,13 +15,12 @@ class SearchDataRepository(){ val updatedDocuments = documents.map { document -> val descriptionFromCode = CategoryData.descriptions[document.categoryCode] val descriptionFromCategory = getTailCategory(document.category) - val updateDocument = document.copy( + document.copy( categoryDescription = descriptionFromCode, categoryTail = descriptionFromCategory ) - updateDocument } - _searchDataList.postValue(updatedDocuments) + callback(updatedDocuments) } } } diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt index 73f9ce34..dd49c552 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt @@ -1,17 +1,22 @@ package campus.tech.kakao.map.viewModel -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import campus.tech.kakao.map.repository.SearchDataRepository +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import campus.tech.kakao.map.repository.SearchResultRepository +import campus.tech.kakao.map.retrofit.Document -class SearchViewModel(application: Application) : AndroidViewModel(application) { - private val repository: SearchDataRepository = SearchDataRepository() +class SearchViewModel(private val repository: SearchResultRepository) : ViewModel() { + private val _searchDataList = MutableLiveData>() + val searchResults: LiveData> get() = _searchDataList - //"DataSearchActivity"에서 사용할 LiveData - val searchResults = repository.searchResults + fun loadResultData(searchQuery: String) { + repository.loadResultMapData(searchQuery) { documents -> + _searchDataList.postValue(documents) + } + } - //검색 결과를 LiveData에 저장 - fun loadResultData(searchQuery:String){ - repository.loadResultMapData(searchQuery) + fun getSearchDataLiveData(): LiveData> { + return searchResults } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt new file mode 100644 index 00000000..a8ee90c6 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt @@ -0,0 +1,15 @@ +package campus.tech.kakao.map.viewModel.factory + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.viewModel.SearchViewModel +import java.lang.IllegalArgumentException + +class SearchViewModelFactory(private val searchResultRepo: SearchResultRepository) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if(modelClass.isAssignableFrom(SearchViewModel::class.java)){ + return SearchViewModel(searchResultRepo) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_data_search.xml b/app/src/main/res/layout/activity_data_search.xml index d45eee2a..8f53007a 100644 --- a/app/src/main/res/layout/activity_data_search.xml +++ b/app/src/main/res/layout/activity_data_search.xml @@ -1,70 +1,80 @@ - + xmlns:tools="http://schemas.android.com/tools"> - + + + - + + - + - - + - + + + + + + + From 514a764385280641e9c47ebb7c978d81b2c91038 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 21:39:51 +0900 Subject: [PATCH 10/32] fix: Remove duplicate files and rename activity folder to view --- .../tech/kakao/map/DataSearchActivityTest.kt | 2 +- .../tech/kakao/map/HomeMapActivityTest.kt | 6 +-- .../tech/kakao/map/MapErrorActivityTest.kt | 4 +- app/src/main/AndroidManifest.xml | 6 +-- .../tech/kakao/map/MapViewModelFactory.kt | 1 + .../tech/kakao/map/PreferenceRepository.kt | 18 ------- .../{activity => view}/DataSearchActivity.kt | 3 +- .../map/{activity => view}/HomeMapActivity.kt | 49 ++++++++++--------- .../{activity => view}/MapErrorActivity.kt | 2 +- .../main/res/layout/activity_data_search.xml | 4 +- .../main/res/layout/activity_map_error.xml | 2 +- 11 files changed, 42 insertions(+), 55 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt rename app/src/main/java/campus/tech/kakao/map/{activity => view}/DataSearchActivity.kt (98%) rename app/src/main/java/campus/tech/kakao/map/{activity => view}/HomeMapActivity.kt (81%) rename app/src/main/java/campus/tech/kakao/map/{activity => view}/MapErrorActivity.kt (94%) diff --git a/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt index bae3afeb..32b5f677 100644 --- a/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt +++ b/app/src/androidTest/java/campus/tech/kakao/map/DataSearchActivityTest.kt @@ -7,7 +7,7 @@ import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.rules.ActivityScenarioRule -import campus.tech.kakao.map.activity.DataSearchActivity +import campus.tech.kakao.map.view.DataSearchActivity import org.junit.Rule import org.junit.Test diff --git a/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt index 1a13f135..2c116de1 100644 --- a/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt +++ b/app/src/androidTest/java/campus/tech/kakao/map/HomeMapActivityTest.kt @@ -13,8 +13,8 @@ import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.rules.ActivityScenarioRule -import campus.tech.kakao.map.activity.DataSearchActivity -import campus.tech.kakao.map.activity.HomeMapActivity +import campus.tech.kakao.map.view.DataSearchActivity +import campus.tech.kakao.map.view.HomeMapActivity import org.junit.After import org.junit.Before import org.junit.Rule @@ -57,7 +57,7 @@ class HomeMapActivityTest { @Test fun 검색바를_클릭하면_검색화면으로_이동() { - onView(withId(R.id.search_home)) + onView(withId(R.id.searchbar_home)) .perform(click()) intended(hasComponent(DataSearchActivity::class.java.name)) } diff --git a/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt b/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt index b6ce747d..e8880f4b 100644 --- a/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt +++ b/app/src/androidTest/java/campus/tech/kakao/map/MapErrorActivityTest.kt @@ -7,8 +7,8 @@ import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.rules.ActivityScenarioRule -import campus.tech.kakao.map.activity.HomeMapActivity -import campus.tech.kakao.map.activity.MapErrorActivity +import campus.tech.kakao.map.view.HomeMapActivity +import campus.tech.kakao.map.view.MapErrorActivity import org.junit.Rule import org.junit.Test diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d8f7a418..1f358101 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,10 +16,10 @@ android:theme="@style/Theme.Map" tools:targetApi="31"> @@ -29,7 +29,7 @@ diff --git a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt index 6a3098e6..982fe11b 100644 --- a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt +++ b/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt @@ -2,6 +2,7 @@ package campus.tech.kakao.map import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.viewModel.MapViewModel import java.lang.IllegalArgumentException diff --git a/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt b/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt deleted file mode 100644 index fcb845bd..00000000 --- a/app/src/main/java/campus/tech/kakao/map/PreferenceRepository.kt +++ /dev/null @@ -1,18 +0,0 @@ -package campus.tech.kakao.map - -import android.content.Context -import android.content.SharedPreferences - -class PreferenceRepository(context: Context) { - - private var sharedPrefs: SharedPreferences = - context.getSharedPreferences("location_data", Context.MODE_PRIVATE) - - fun setString(key: String, value: String) { - sharedPrefs.edit().putString(key, value).apply() - } - - fun getString(key: String, value: String?): String { - return sharedPrefs.getString(key, value).toString() - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt similarity index 98% rename from app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt rename to app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index 492b667b..bc8ecce6 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.activity +package campus.tech.kakao.map.view import android.content.Intent import android.os.Bundle @@ -54,7 +54,6 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) //Adapter 초기화 - // Adapter 초기화 searchResultDataAdapter = SearchDataAdapter(emptyList(), recentViewModel, this) binding.searchResulListView.adapter = searchResultDataAdapter binding.recentSearchListView.adapter = diff --git a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt similarity index 81% rename from app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt rename to app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index b86c4081..47a86f10 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -1,19 +1,20 @@ -package campus.tech.kakao.map.activity +package campus.tech.kakao.map.view -import android.annotation.SuppressLint import android.content.Intent import android.graphics.Color import android.os.Bundle -import android.widget.EditText import android.widget.TextView import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout +import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import campus.tech.kakao.map.viewModel.factory.MapViewModelFactory import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.R import campus.tech.kakao.map.data.LocationDataContract +import campus.tech.kakao.map.databinding.ActivityHomeMapBinding +import campus.tech.kakao.map.databinding.MapDetailBottomSheetBinding import campus.tech.kakao.map.viewModel.MapErrorViewModel import campus.tech.kakao.map.viewModel.MapViewModel import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -21,46 +22,51 @@ import com.kakao.vectormap.KakaoMap import com.kakao.vectormap.KakaoMapReadyCallback import com.kakao.vectormap.LatLng import com.kakao.vectormap.MapLifeCycleCallback -import com.kakao.vectormap.MapView import com.kakao.vectormap.label.LabelOptions import com.kakao.vectormap.label.LabelStyle import com.kakao.vectormap.label.LabelStyles class HomeMapActivity : AppCompatActivity() { - private lateinit var mapView: MapView - private lateinit var searchBar: EditText - private val bottomSheet: ConstraintLayout by lazy { findViewById(R.id.bottomSheet) } + private lateinit var bindingHomeMap: ActivityHomeMapBinding + //private lateinit var bindingBottomSheet: MapDetailBottomSheetBinding private lateinit var bottomBehavior: BottomSheetBehavior - private lateinit var placeNameTextView: TextView - private lateinit var placeAddressTextView: TextView private lateinit var mapViewModel: MapViewModel private lateinit var prefersRepo: PreferenceRepository - @SuppressLint("MissingInflatedId") + private lateinit var placeNameTextView: TextView + private lateinit var placeAddressTextView: TextView + + lateinit var locationName: String + lateinit var locationAddress: String + + private val bottomSheet: ConstraintLayout by lazy { findViewById(R.id.bottomSheet) } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() - setContentView(R.layout.activity_home_map) + + bindingHomeMap = DataBindingUtil.setContentView(this, R.layout.activity_home_map) + //bindingBottomSheet = DataBindingUtil.setContentView(this, R.layout.map_detail_bottom_sheet) prefersRepo = PreferenceRepository(applicationContext) mapViewModel = ViewModelProvider(this, MapViewModelFactory(prefersRepo))[MapViewModel::class.java] - val name = intent.getStringExtra(LocationDataContract.LOCATION_NAME) - val address = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS) + locationName = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() + locationAddress = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() val latitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() val longitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() - mapView = findViewById(R.id.mapView) placeNameTextView = findViewById(R.id.placeName) placeAddressTextView = findViewById(R.id.placeAddress) bottomBehavior = BottomSheetBehavior.from(bottomSheet) + val mapErrorViewModel: MapErrorViewModel = ViewModelProvider(this)[MapErrorViewModel::class.java] val intentError = Intent(this, MapErrorActivity::class.java) //KaKao Map UI에 띄우기 - mapView.start(object : MapLifeCycleCallback() { + bindingHomeMap.mapView.start(object : MapLifeCycleCallback() { override fun onMapDestroy() { } @@ -86,7 +92,7 @@ class HomeMapActivity : AppCompatActivity() { ) val options = LabelOptions.from(LatLng.from(latitude, longitude)).setStyles(style) - .setTexts(name) + .setTexts(locationName) val layer = p0.labelManager?.layer layer?.addLabel(options) } @@ -112,15 +118,14 @@ class HomeMapActivity : AppCompatActivity() { }) if (latitude != null && longitude != null) { - placeNameTextView.text = name - placeAddressTextView.text = address + placeNameTextView.text = locationName + placeAddressTextView.text = locationAddress bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED } else { bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN } - searchBar = findViewById(R.id.search_home) - searchBar.setOnClickListener { + bindingHomeMap.searchbarHome.setOnClickListener { val intent = Intent(this, DataSearchActivity::class.java) startActivity(intent) } @@ -128,12 +133,12 @@ class HomeMapActivity : AppCompatActivity() { override fun onResume() { super.onResume() - mapView.resume() + bindingHomeMap.mapView.resume() } override fun onPause() { super.onPause() - mapView.pause() + bindingHomeMap.mapView.pause() } override fun onDestroy() { diff --git a/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt similarity index 94% rename from app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt rename to app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt index 7a11b504..0b4b8091 100644 --- a/app/src/main/java/campus/tech/kakao/map/activity/MapErrorActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt @@ -1,4 +1,4 @@ -package campus.tech.kakao.map.activity +package campus.tech.kakao.map.view import android.os.Bundle import androidx.activity.OnBackPressedCallback diff --git a/app/src/main/res/layout/activity_data_search.xml b/app/src/main/res/layout/activity_data_search.xml index 1842ca28..6bc6b12b 100644 --- a/app/src/main/res/layout/activity_data_search.xml +++ b/app/src/main/res/layout/activity_data_search.xml @@ -6,14 +6,14 @@ + type="campus.tech.kakao.map.view.DataSearchActivity" /> + tools:context=".view.DataSearchActivity"> + tools:context=".view.MapErrorActivity"> Date: Fri, 26 Jul 2024 21:41:10 +0900 Subject: [PATCH 11/32] fix: Remove duplicate files --- .../tech/kakao/map/MapViewModelFactory.kt | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt diff --git a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt deleted file mode 100644 index 982fe11b..00000000 --- a/app/src/main/java/campus/tech/kakao/map/MapViewModelFactory.kt +++ /dev/null @@ -1,17 +0,0 @@ -package campus.tech.kakao.map - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.repository.PreferenceRepository -import campus.tech.kakao.map.viewModel.MapViewModel -import java.lang.IllegalArgumentException - -class MapViewModelFactory(repository: PreferenceRepository): ViewModelProvider.Factory { - private val prefersRepo = repository - override fun create(modelClass: Class): T { - if(modelClass.isAssignableFrom(MapViewModel::class.java)){ - return MapViewModel(prefersRepo) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file From e881ef1c876dc04a4256b37400e6281e77a25d77 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Fri, 26 Jul 2024 22:37:46 +0900 Subject: [PATCH 12/32] remove: Remove unused files --- .../kakao/map/viewModel/RecentViewModel.kt | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt deleted file mode 100644 index 0118a719..00000000 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/RecentViewModel.kt +++ /dev/null @@ -1,47 +0,0 @@ -package campus.tech.kakao.map.viewModel - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import campus.tech.kakao.map.dataRepository.RecentDataRepository -import campus.tech.kakao.map.data.RecentSearchData - -class RecentViewModel(application: Application) : AndroidViewModel(application) { - private val repository: RecentDataRepository = RecentDataRepository(application) - - private val _recentDataList = MutableLiveData>() - - init { - _recentDataList.value = repository.getRecentSearchDataList() - } - - fun addRecentData(data: String, address: String, time: Long) { - val currentList = _recentDataList.value.orEmpty().toMutableList() - val selectData = RecentSearchData(data, address, time) - - if (checkExist(currentList, selectData)) { - repository.insertSearchData(selectData) - } else { - repository.updateTime(selectData) - } - _recentDataList.value = repository.getRecentSearchDataList() - } - - //DB에 데이터 추가 전 중복 검사 (현재 DB에 없으면 true) - private fun checkExist( - currentList: MutableList, - data: RecentSearchData - ): Boolean { - return !currentList.any { it.name == data.name && it.address == data.address } - } - - fun getRecentDataLiveData(): LiveData> { - return _recentDataList - } - - fun deleteRecentData(data: String, address: String) { - repository.deleteSearchData(data, address) - _recentDataList.value = repository.getRecentSearchDataList() - } -} \ No newline at end of file From 40e8185bf3866a2c87e5316ec3031c889b278d9a Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Sun, 28 Jul 2024 01:58:26 +0900 Subject: [PATCH 13/32] =?UTF-8?q?[=EC=A3=BC=EC=9D=98]refactor:=20Attempt?= =?UTF-8?q?=20data=20binding=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 폴더명을 activiy에서 view로 변경하면서 데이터 바인딩 관련 미완성 코드가 포함됨 - 오류 방지를 위해 관련 변경사항 커밋함 (참고 커밋: 514a764385280641e9c47ebb7c978d81b2c91038) - 주의사항 : 데이터 바인딩 부분은 현재 미완성 상태로 추가 수정이 필요함 --- app/src/main/res/layout/activity_home_map.xml | 108 ++++++++++-------- .../res/layout/map_detail_bottom_sheet.xml | 66 ++++++----- .../main/res/layout/recent_search_item.xml | 62 +++++----- 3 files changed, 133 insertions(+), 103 deletions(-) diff --git a/app/src/main/res/layout/activity_home_map.xml b/app/src/main/res/layout/activity_home_map.xml index df2b9955..eba9a43b 100644 --- a/app/src/main/res/layout/activity_home_map.xml +++ b/app/src/main/res/layout/activity_home_map.xml @@ -1,55 +1,65 @@ - - - + + + + + + - - - - - - + tools:context=".view.HomeMapActivity"> + + + + + + + + + + + - - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/map_detail_bottom_sheet.xml b/app/src/main/res/layout/map_detail_bottom_sheet.xml index a79d2f5d..cf983722 100644 --- a/app/src/main/res/layout/map_detail_bottom_sheet.xml +++ b/app/src/main/res/layout/map_detail_bottom_sheet.xml @@ -1,33 +1,43 @@ - + - + + + - + android:background="@color/white" + app:behavior_hideable="true" + app:layout_behavior="@string/bottom_sheet_behavior"> + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/recent_search_item.xml b/app/src/main/res/layout/recent_search_item.xml index 606b3977..c8430949 100644 --- a/app/src/main/res/layout/recent_search_item.xml +++ b/app/src/main/res/layout/recent_search_item.xml @@ -1,33 +1,43 @@ - + + + + + - + android:layout_height="wrap_content" + xmlns:app="http://schemas.android.com/apk/res-auto"> - + + + - \ No newline at end of file + + + From f6201acdf96dcaee9e86d485c9c7178f40ac5283 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Sun, 28 Jul 2024 02:22:55 +0900 Subject: [PATCH 14/32] fix: Display error messages on error screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 에러 화면에 에러 메시지가 표시되지 않는 문제 해결 참고 커밋: b9171d4c1c883d696e32798dfdaf9f0cadf9aa99 변경 사항: [HomeMapActivity] - 복잡도를 낮추기 위해서 view가 하나의 viewModel을 사용하도록 수정 [MapErrorActivity] - 데이터 바인딩 관련 코드 추가 - 기능별로 함수 분리 [MapErrorViewModel] - setErrorMsg로 함수명 변경 - 에러 메세지가 null이 아닌지 검사하는 코드 추가, 에러 메세지의 공백을 없애는 코드 추가 [activity_map_error] - 데이터 바인딩 관련 코드 추가 [MapErrorViewModelTest] - 바뀐 setErrorMsg()함수 반영 --- .../tech/kakao/map/view/HomeMapActivity.kt | 15 ++++----- .../tech/kakao/map/view/MapErrorActivity.kt | 31 ++++++++++++++++++- .../kakao/map/viewModel/MapErrorViewModel.kt | 8 +++-- .../main/res/layout/activity_map_error.xml | 14 ++++++--- .../tech/kakao/map/MapErrorViewModelTest.kt | 8 ++--- 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index 47a86f10..65e00e1f 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -14,8 +14,6 @@ import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.R import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.databinding.ActivityHomeMapBinding -import campus.tech.kakao.map.databinding.MapDetailBottomSheetBinding -import campus.tech.kakao.map.viewModel.MapErrorViewModel import campus.tech.kakao.map.viewModel.MapViewModel import com.google.android.material.bottomsheet.BottomSheetBehavior import com.kakao.vectormap.KakaoMap @@ -28,6 +26,7 @@ import com.kakao.vectormap.label.LabelStyles class HomeMapActivity : AppCompatActivity() { private lateinit var bindingHomeMap: ActivityHomeMapBinding + //private lateinit var bindingBottomSheet: MapDetailBottomSheetBinding private lateinit var bottomBehavior: BottomSheetBehavior private lateinit var mapViewModel: MapViewModel @@ -62,17 +61,13 @@ class HomeMapActivity : AppCompatActivity() { bottomBehavior = BottomSheetBehavior.from(bottomSheet) - val mapErrorViewModel: MapErrorViewModel = ViewModelProvider(this)[MapErrorViewModel::class.java] - val intentError = Intent(this, MapErrorActivity::class.java) - //KaKao Map UI에 띄우기 bindingHomeMap.mapView.start(object : MapLifeCycleCallback() { override fun onMapDestroy() { } override fun onMapError(p0: Exception?) { - mapErrorViewModel.setErrorDetail(p0.toString()) - startActivity(intentError) + setErrorIntent(p0) } }, object : KakaoMapReadyCallback() { @@ -148,4 +143,10 @@ class HomeMapActivity : AppCompatActivity() { intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE) ?.let { mapViewModel.saveLocation(LocationDataContract.LOCATION_LONGITUDE, it) } } + + private fun setErrorIntent(errorMsg: Exception?) { + val intentError = Intent(this@HomeMapActivity, MapErrorActivity::class.java) + intentError.putExtra("ERROR_MESSAGE", errorMsg.toString()) + startActivity(intentError) + } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt index 0b4b8091..e7f769d0 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt @@ -4,14 +4,43 @@ import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity +import androidx.databinding.DataBindingUtil +import androidx.lifecycle.ViewModelProvider import campus.tech.kakao.map.R +import campus.tech.kakao.map.databinding.ActivityMapErrorBinding +import campus.tech.kakao.map.viewModel.MapErrorViewModel class MapErrorActivity : AppCompatActivity() { + private lateinit var binding: ActivityMapErrorBinding + private lateinit var viewModel: MapErrorViewModel + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() - setContentView(R.layout.activity_map_error) + setBinding() + setViewModel() + setErrorMsg() + clickBackBtn() + } + + private fun setBinding() { + binding = DataBindingUtil.setContentView(this, R.layout.activity_map_error) + binding.activity = this + } + + private fun setViewModel() { + viewModel = ViewModelProvider(this)[MapErrorViewModel::class.java] + binding.lifecycleOwner = this + binding.viewModel = viewModel + } + + private fun setErrorMsg() { + val errorMsg = intent.getStringExtra("ERROR_MESSAGE") + viewModel.setErrorMsg(errorMsg) + } + + private fun clickBackBtn() { onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { finishAffinity() diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt index cd2532df..bf38f6f9 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt @@ -4,11 +4,13 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -class MapErrorViewModel: ViewModel() { +class MapErrorViewModel : ViewModel() { private val _errorMessage = MutableLiveData() val errorMessage: LiveData get() = _errorMessage - fun setErrorDetail(errorMessage: String){ - _errorMessage.value = errorMessage.substringAfterLast(":") + fun setErrorMsg(error: String?) { + if (error != null) { + _errorMessage.value = error.substringAfterLast(":").trim() + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map_error.xml b/app/src/main/res/layout/activity_map_error.xml index a9678e56..4e6f5303 100644 --- a/app/src/main/res/layout/activity_map_error.xml +++ b/app/src/main/res/layout/activity_map_error.xml @@ -1,13 +1,19 @@ - + + + + + app:layout_constraintTop_toTopOf="parent" /> @Before - fun setUp(){ + fun setUp() { MockitoAnnotations.initMocks(this) viewModel = MapErrorViewModel() viewModel.errorMessage.observeForever(errorMessageObserver) } @Test - fun 오류메시지가_정상적으로_설정됨() = runTest{ - val error = "java.lang.Exception:401" - viewModel.setErrorDetail(error) + fun 오류메시지가_정상적으로_설정됨() = runTest { + val error = "java.lang.Exception: 401" + viewModel.setErrorMsg(error) Mockito.verify(errorMessageObserver).onChanged("401") } } \ No newline at end of file From 7ec08e2fab362ad6e48cfedfe82f645dca5efadd Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Sun, 28 Jul 2024 02:58:05 +0900 Subject: [PATCH 15/32] fix: Add dependency injection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 코드 통일성을 위해 의존성 주입 관련 코드 추가 --- .../main/java/campus/tech/kakao/map/view/MapErrorActivity.kt | 2 ++ .../campus/tech/kakao/map/viewModel/MapErrorViewModel.kt | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt index e7f769d0..f8ec5195 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/MapErrorActivity.kt @@ -9,7 +9,9 @@ import androidx.lifecycle.ViewModelProvider import campus.tech.kakao.map.R import campus.tech.kakao.map.databinding.ActivityMapErrorBinding import campus.tech.kakao.map.viewModel.MapErrorViewModel +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class MapErrorActivity : AppCompatActivity() { private lateinit var binding: ActivityMapErrorBinding private lateinit var viewModel: MapErrorViewModel diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt index bf38f6f9..19c99d71 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapErrorViewModel.kt @@ -3,8 +3,11 @@ package campus.tech.kakao.map.viewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class MapErrorViewModel : ViewModel() { +@HiltViewModel +class MapErrorViewModel @Inject constructor() : ViewModel() { private val _errorMessage = MutableLiveData() val errorMessage: LiveData get() = _errorMessage From 77bc26c2a3bc649e7eb1da4b9ad6f922ef1ef090 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Sun, 28 Jul 2024 03:21:54 +0900 Subject: [PATCH 16/32] remove: Remove unused and duplicate files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 참고 사항: - 파일의 폴더를 변경하는 과정에서 의도치 않게 파일이 복사 된 것 같음 - 관련 커밋: 3531fc60a95d211cf868193c7009ece363817eb6 --- .../dataRepository/RecentDataRepository.kt | 71 ------------------- .../dataRepository/SearchDataRepository.kt | 40 ----------- 2 files changed, 111 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt deleted file mode 100644 index 97d7279a..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataRepository/RecentDataRepository.kt +++ /dev/null @@ -1,71 +0,0 @@ -package campus.tech.kakao.map.dataRepository - -import android.content.ContentValues -import android.content.Context -import android.database.Cursor -import campus.tech.kakao.map.dBHelper.RecentDBHelper -import campus.tech.kakao.map.dataContract.RecentDataContract -import campus.tech.kakao.map.data.RecentSearchData - -class RecentDataRepository(context: Context) { - private val db: RecentDBHelper = RecentDBHelper(context) - private val wDb = db.writableDatabase - private val rDb = db.readableDatabase - - fun insertSearchData(data: RecentSearchData) { - val cv = ContentValues().apply { - put(RecentDataContract.TABLE_COLUMN_NAME, data.name) - put(RecentDataContract.TABLE_COLUMN_ADDRESS, data.address) - put(RecentDataContract.TABLE_COLUMN_TIME, data.time) - } - wDb.insert(RecentDataContract.TABLE_NAME, null, cv) - } - - fun getRecentSearchDataList(): List { - val cursor: Cursor = rDb.query( - RecentDataContract.TABLE_NAME, - null, - null, - null, - null, - null, - "${RecentDataContract.TABLE_COLUMN_TIME} DESC" - ) - val recentDataList = mutableListOf() - - while (cursor.moveToNext()) { - val name = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_NAME)) - val address = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_ADDRESS)) - val time = - cursor.getString(cursor.getColumnIndexOrThrow(RecentDataContract.TABLE_COLUMN_TIME)) - - recentDataList.add(RecentSearchData(name, address, time.toLong())) - } - cursor.close() - - return recentDataList - } - - fun deleteSearchData(data: String, address: String) { - wDb.delete( - RecentDataContract.TABLE_NAME, - "${RecentDataContract.TABLE_COLUMN_NAME} = ? AND ${RecentDataContract.TABLE_COLUMN_ADDRESS} = ?", - arrayOf(data, address) - ) - } - - fun updateTime(data: RecentSearchData) { - val cv = ContentValues().apply { - put(RecentDataContract.TABLE_COLUMN_TIME, data.time) - } - - wDb.update( - RecentDataContract.TABLE_NAME, - cv, - "${RecentDataContract.TABLE_COLUMN_NAME} = ?", - arrayOf(data.name) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt b/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt deleted file mode 100644 index acab6899..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataRepository/SearchDataRepository.kt +++ /dev/null @@ -1,40 +0,0 @@ -package campus.tech.kakao.map.dataRepository - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import campus.tech.kakao.map.retrofit.CategoryData -import campus.tech.kakao.map.retrofit.Document -import campus.tech.kakao.map.retrofit.RetrofitAPI.getResultFromAPI - -class SearchDataRepository(){ - private val _searchDataList = MutableLiveData>() - val searchResults: LiveData> - get() = _searchDataList - - //검색 결과 가공 후 LiveData에 저장 - fun loadResultMapData(data: String) { - getResultFromAPI(data) { response -> - if (response.isSuccessful) { - val body = response.body() - body?.documents?.let { documents -> - val updatedDocuments = documents.map { document -> - val descriptionFromCode = CategoryData.descriptions[document.categoryCode] - val descriptionFromCategory = getTailCategory(document.category) - val updateDocument = document.copy( - categoryDescription = descriptionFromCode, - categoryTail = descriptionFromCategory - ) - updateDocument - } - _searchDataList.postValue(updatedDocuments) - } - } - } - } - - //API 데이터에서 "category_name" 문자열이 길기 때문에, 충분한 의미 전달이 되는 키워드를 임의로 추출 - private fun getTailCategory(category: String): String { - val parts = category.split(">") - return if (parts.size > 1) parts[1].trim() else parts.last().trim() - } -} \ No newline at end of file From dacda2ca529c1ae4296cf8e439696b4693fe1e2f Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Sun, 28 Jul 2024 03:26:32 +0900 Subject: [PATCH 17/32] remove: Remove unused files --- .../tech/kakao/map/dBHelper/RecentDBHelper.kt | 28 ------------------- .../tech/kakao/map/data/RecentSearchData.kt | 4 --- .../map/dataContract/LocationDataContract.kt | 8 ------ .../map/dataContract/RecentDataContract.kt | 10 ------- .../map/listener/RecentAdapterListener.kt | 5 ---- .../map/listener/SearchAdapterListener.kt | 5 ---- 6 files changed, 60 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt diff --git a/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt b/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt deleted file mode 100644 index 744b568f..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dBHelper/RecentDBHelper.kt +++ /dev/null @@ -1,28 +0,0 @@ -package campus.tech.kakao.map.dBHelper - -import android.content.Context -import android.database.sqlite.SQLiteDatabase -import android.database.sqlite.SQLiteOpenHelper -import campus.tech.kakao.map.dataContract.RecentDataContract - -//version 2: DB에 time 컬럼을 추가함 -//version 3" DB에 address 컬럼을 추가함 -class RecentDBHelper(context: Context) : SQLiteOpenHelper(context, "RecentData.db", null, 3) { - override fun onCreate(db: SQLiteDatabase?) { - createRecentDataTable(db) - } - - override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { - db?.execSQL("DROP TABLE IF EXISTS ${RecentDataContract.TABLE_NAME}") - createRecentDataTable(db) - } - - private fun createRecentDataTable(db: SQLiteDatabase?) { - db?.execSQL( - "CREATE TABLE ${RecentDataContract.TABLE_NAME} (" + - "${RecentDataContract.TABLE_COLUMN_NAME} varchar(30) NOT NULL, " + - "${RecentDataContract.TABLE_COLUMN_ADDRESS} varchar(50) NOT NULL, " + - "${RecentDataContract.TABLE_COLUMN_TIME} integer NOT NULL);" - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt b/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt deleted file mode 100644 index 31bddf16..00000000 --- a/app/src/main/java/campus/tech/kakao/map/data/RecentSearchData.kt +++ /dev/null @@ -1,4 +0,0 @@ -package campus.tech.kakao.map.data - - -data class RecentSearchData(val name: String, val address: String, val time: Long) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt b/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt deleted file mode 100644 index 1fc74189..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataContract/LocationDataContract.kt +++ /dev/null @@ -1,8 +0,0 @@ -package campus.tech.kakao.map.dataContract - -object LocationDataContract { - const val LOCATION_NAME = "name" - const val LOCATION_ADDRESS = "address" - const val LOCATION_LATITUDE = "latitude" - const val LOCATION_LONGITUDE = "longitude" -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt b/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt deleted file mode 100644 index 352f38a9..00000000 --- a/app/src/main/java/campus/tech/kakao/map/dataContract/RecentDataContract.kt +++ /dev/null @@ -1,10 +0,0 @@ -package campus.tech.kakao.map.dataContract - -import android.provider.BaseColumns - -object RecentDataContract : BaseColumns { - const val TABLE_NAME = "RecentData" - const val TABLE_COLUMN_NAME = "name" - const val TABLE_COLUMN_ADDRESS = "address" - const val TABLE_COLUMN_TIME = "recentSearchTime" -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt deleted file mode 100644 index 05716243..00000000 --- a/app/src/main/java/campus/tech/kakao/map/listener/RecentAdapterListener.kt +++ /dev/null @@ -1,5 +0,0 @@ -package campus.tech.kakao.map.listener - -interface RecentAdapterListener { - fun autoSearch(searchData: String) -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt b/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt deleted file mode 100644 index 11481426..00000000 --- a/app/src/main/java/campus/tech/kakao/map/listener/SearchAdapterListener.kt +++ /dev/null @@ -1,5 +0,0 @@ -package campus.tech.kakao.map.listener - -interface SearchAdapterListener { - fun displaySearchLocation(name: String, address: String, latitude: String, longitude: String) -} \ No newline at end of file From 405907432b69f3ee7f4a931cdc2e2c6bcbfdeb1d Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 17:42:49 +0900 Subject: [PATCH 18/32] =?UTF-8?q?[step1=20=EC=88=98=EC=A0=95=20=EB=B0=98?= =?UTF-8?q?=EC=98=81]=20refactor:=20Apply=20Hilt=20for=20dependency=20inje?= =?UTF-8?q?ction=20in=20DataSearchActivity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 참고 커밋 : 518a06c --- .../map/repository/SearchHistoryRepository.kt | 8 ++++- .../tech/kakao/map/view/DataSearchActivity.kt | 30 ++++++++++--------- .../tech/kakao/map/viewModel/DBViewModel.kt | 9 ++++-- .../viewModel/factory/DBViewModelFactory.kt | 18 ----------- 4 files changed, 30 insertions(+), 35 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt index 5043473e..00d4a52d 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt @@ -5,10 +5,16 @@ import android.util.Log import campus.tech.kakao.map.data.room.SearchHistoryDao import campus.tech.kakao.map.data.room.SearchHistoryData import campus.tech.kakao.map.data.room.SearchHistoryDatabase +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton -class SearchHistoryRepository(context: Context) { +@Singleton +class SearchHistoryRepository @Inject constructor( + @ApplicationContext context: Context +) { private val searchHistoryDao: SearchHistoryDao = SearchHistoryDatabase.getDatabase(context).searchHistoryDao() diff --git a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index bc8ecce6..ed05a790 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -6,36 +6,36 @@ import android.text.Editable import android.text.TextWatcher import android.view.View import androidx.appcompat.app.AppCompatActivity -import androidx.databinding.DataBindingUtil import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager -import campus.tech.kakao.map.R import campus.tech.kakao.map.adapter.listener.RecentAdapterListener import campus.tech.kakao.map.adapter.listener.SearchAdapterListener import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.databinding.ActivityDataSearchBinding -import campus.tech.kakao.map.repository.SearchHistoryRepository import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.viewModel.SearchViewModel -import campus.tech.kakao.map.viewModel.factory.DBViewModelFactory import campus.tech.kakao.map.viewModel.factory.SearchViewModelFactory +import dagger.hilt.android.AndroidEntryPoint +import androidx.activity.viewModels +@AndroidEntryPoint class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAdapterListener { + private lateinit var binding: ActivityDataSearchBinding + + private lateinit var searchViewModel: SearchViewModel //검색 결과 관리 //추후 계획: step2에서 수정이 있었던 부분이기 때문에, step2에서 Hilt 적용 + private val recentViewModel: DBViewModel by viewModels() //최근 검색어 관리 + private lateinit var searchResultRepo: SearchResultRepository //검색 결과 관리 - private lateinit var dbRepo: SearchHistoryRepository //최근 검색어 데이터 관리 - private lateinit var searchViewModel: SearchViewModel //검색 결과 관리 - private lateinit var recentViewModel: DBViewModel //최근 검색어 관리 private lateinit var searchResultDataAdapter: SearchDataAdapter //검색 결과 표시 위함 - private lateinit var binding: ActivityDataSearchBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_data_search) - binding = DataBindingUtil.setContentView(this, R.layout.activity_data_search) + + setBind() //ViewModel 생성 searchResultRepo = SearchResultRepository() @@ -44,10 +44,6 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda SearchViewModelFactory(searchResultRepo) )[SearchViewModel::class.java] - dbRepo = SearchHistoryRepository(this) - recentViewModel = - ViewModelProvider(this, DBViewModelFactory(dbRepo))[DBViewModel::class.java] - //RecyclerView Layout 매니저 설정 (스크롤 방향 설정) binding.searchResulListView.layoutManager = LinearLayoutManager(this) binding.recentSearchListView.layoutManager = @@ -80,6 +76,12 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda }) } + private fun setBind(){ + binding = ActivityDataSearchBinding.inflate(layoutInflater) + val view = binding.root + setContentView(view) + } + private fun setTextWatcher() { binding.searchBar.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt index eca7df7e..5e7d4e05 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt @@ -7,9 +7,14 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import campus.tech.kakao.map.data.room.SearchHistoryData import campus.tech.kakao.map.repository.SearchHistoryRepository +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import javax.inject.Inject -class DBViewModel(private val searchHistoryRepo: SearchHistoryRepository) : ViewModel() { +@HiltViewModel +class DBViewModel @Inject constructor( + private val searchHistoryRepo: SearchHistoryRepository +) : ViewModel() { private val _searchHistoryDataList = MutableLiveData>() private val searchHistoryDataList: LiveData> = _searchHistoryDataList @@ -37,7 +42,7 @@ class DBViewModel(private val searchHistoryRepo: SearchHistoryRepository) : View } suspend fun deleteRecentData(data: String, address: String, time: Long) { - Log.d("yeong","DBViewModel: 여기까지 옴") + Log.d("yeong", "DBViewModel: 여기까지 옴") searchHistoryRepo.deleteSearchData(data, address, time) _searchHistoryDataList.value = searchHistoryRepo.getSearchHistory() } diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt deleted file mode 100644 index 7559a578..00000000 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/DBViewModelFactory.kt +++ /dev/null @@ -1,18 +0,0 @@ -package campus.tech.kakao.map.viewModel.factory - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.repository.SearchHistoryRepository -import campus.tech.kakao.map.viewModel.DBViewModel -import java.lang.IllegalArgumentException - -class DBViewModelFactory(repository: SearchHistoryRepository) : ViewModelProvider.Factory { - private val dbRepo = repository - - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(DBViewModel::class.java)) { - return DBViewModel(dbRepo) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file From e3e35429a35b491ebf7be8e33aaf78af00a5ad6c Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 17:57:59 +0900 Subject: [PATCH 19/32] =?UTF-8?q?[step1=20=EC=88=98=EC=A0=95=20=EB=B0=98?= =?UTF-8?q?=EC=98=81]refactor:=20Apply=20Hilt=20for=20dependency=20injecti?= =?UTF-8?q?on=20in=20HomeMapActivity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 참고 커밋 : 16a8421 --- .../map/repository/PreferenceRepository.kt | 8 ++- .../tech/kakao/map/view/HomeMapActivity.kt | 49 +++++++++---------- .../tech/kakao/map/viewModel/MapViewModel.kt | 9 ++-- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt index 23595143..37183840 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/PreferenceRepository.kt @@ -2,8 +2,14 @@ package campus.tech.kakao.map.repository import android.content.Context import android.content.SharedPreferences +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton -class PreferenceRepository(context: Context) { +@Singleton +class PreferenceRepository @Inject constructor( + @ApplicationContext context: Context +) { private var sharedPrefs: SharedPreferences = context.getSharedPreferences("location_data", Context.MODE_PRIVATE) diff --git a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index 65e00e1f..36339523 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -7,10 +7,6 @@ import android.widget.TextView import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout -import androidx.databinding.DataBindingUtil -import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.viewModel.factory.MapViewModelFactory -import campus.tech.kakao.map.repository.PreferenceRepository import campus.tech.kakao.map.R import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.databinding.ActivityHomeMapBinding @@ -23,36 +19,29 @@ import com.kakao.vectormap.MapLifeCycleCallback import com.kakao.vectormap.label.LabelOptions import com.kakao.vectormap.label.LabelStyle import com.kakao.vectormap.label.LabelStyles +import dagger.hilt.android.AndroidEntryPoint +import androidx.activity.viewModels +@AndroidEntryPoint class HomeMapActivity : AppCompatActivity() { - private lateinit var bindingHomeMap: ActivityHomeMapBinding - - //private lateinit var bindingBottomSheet: MapDetailBottomSheetBinding - private lateinit var bottomBehavior: BottomSheetBehavior - private lateinit var mapViewModel: MapViewModel - private lateinit var prefersRepo: PreferenceRepository + private lateinit var binding: ActivityHomeMapBinding private lateinit var placeNameTextView: TextView private lateinit var placeAddressTextView: TextView - lateinit var locationName: String - lateinit var locationAddress: String + private val mapViewModel: MapViewModel by viewModels() private val bottomSheet: ConstraintLayout by lazy { findViewById(R.id.bottomSheet) } + private lateinit var bottomBehavior: BottomSheetBehavior override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() - bindingHomeMap = DataBindingUtil.setContentView(this, R.layout.activity_home_map) - //bindingBottomSheet = DataBindingUtil.setContentView(this, R.layout.map_detail_bottom_sheet) + setBinding() - prefersRepo = PreferenceRepository(applicationContext) - mapViewModel = - ViewModelProvider(this, MapViewModelFactory(prefersRepo))[MapViewModel::class.java] - - locationName = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() - locationAddress = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() + val name = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() + val address = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() val latitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() val longitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() @@ -62,7 +51,7 @@ class HomeMapActivity : AppCompatActivity() { bottomBehavior = BottomSheetBehavior.from(bottomSheet) //KaKao Map UI에 띄우기 - bindingHomeMap.mapView.start(object : MapLifeCycleCallback() { + binding.mapView.start(object : MapLifeCycleCallback() { override fun onMapDestroy() { } @@ -87,7 +76,7 @@ class HomeMapActivity : AppCompatActivity() { ) val options = LabelOptions.from(LatLng.from(latitude, longitude)).setStyles(style) - .setTexts(locationName) + .setTexts(name) val layer = p0.labelManager?.layer layer?.addLabel(options) } @@ -113,14 +102,14 @@ class HomeMapActivity : AppCompatActivity() { }) if (latitude != null && longitude != null) { - placeNameTextView.text = locationName - placeAddressTextView.text = locationAddress + placeNameTextView.text = name + placeAddressTextView.text = address bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED } else { bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN } - bindingHomeMap.searchbarHome.setOnClickListener { + binding.searchbarHome.setOnClickListener { val intent = Intent(this, DataSearchActivity::class.java) startActivity(intent) } @@ -128,12 +117,12 @@ class HomeMapActivity : AppCompatActivity() { override fun onResume() { super.onResume() - bindingHomeMap.mapView.resume() + binding.mapView.resume() } override fun onPause() { super.onPause() - bindingHomeMap.mapView.pause() + binding.mapView.pause() } override fun onDestroy() { @@ -149,4 +138,10 @@ class HomeMapActivity : AppCompatActivity() { intentError.putExtra("ERROR_MESSAGE", errorMsg.toString()) startActivity(intentError) } + + private fun setBinding(){ + binding = ActivityHomeMapBinding.inflate(layoutInflater) + val view = binding.root + setContentView(view) + } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt index fbdfaf96..f06373eb 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt @@ -2,10 +2,13 @@ package campus.tech.kakao.map.viewModel import androidx.lifecycle.ViewModel import campus.tech.kakao.map.repository.PreferenceRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject - -class MapViewModel(repository: PreferenceRepository) : ViewModel() { - private val prefersRepo = repository +@HiltViewModel +class MapViewModel @Inject constructor( + private val prefersRepo: PreferenceRepository +) : ViewModel() { fun saveLocation(locationKey: String, data: String) { prefersRepo.setString(locationKey, data) From 02c6e1301f9b0f56541192b7d05504cf4371a411 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 18:35:00 +0900 Subject: [PATCH 20/32] refactor: Refactor DataSearchActivity to use Hilt for injecting SearchViewModel --- .../map/repository/SearchResultRepository.kt | 9 ++++++--- .../campus/tech/kakao/map/retrofit/RetrofitAPI.kt | 11 +++++++++-- .../tech/kakao/map/view/DataSearchActivity.kt | 15 ++------------- .../tech/kakao/map/viewModel/SearchViewModel.kt | 8 +++++++- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt index 091d274c..9ae31249 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchResultRepository.kt @@ -2,13 +2,16 @@ package campus.tech.kakao.map.repository import campus.tech.kakao.map.retrofit.CategoryData import campus.tech.kakao.map.retrofit.Document -import campus.tech.kakao.map.retrofit.RetrofitAPI.getResultFromAPI +import campus.tech.kakao.map.retrofit.RetrofitAPI +import javax.inject.Inject -class SearchResultRepository { +class SearchResultRepository @Inject constructor( + private val retrofitAPI: RetrofitAPI +) { //검색 결과 가공 fun loadResultMapData(data: String, callback: (List) -> Unit) { - getResultFromAPI(data) { response -> + retrofitAPI.getResultFromAPI(data) { response -> if (response.isSuccessful) { val body = response.body() body?.documents?.let { documents -> diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt index 200f12fb..e6ea5058 100644 --- a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt @@ -2,15 +2,22 @@ package campus.tech.kakao.map.retrofit import android.util.Log import campus.tech.kakao.map.BuildConfig +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import retrofit2.Call import retrofit2.Callback import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Inject +import javax.inject.Singleton -object RetrofitAPI { +@Singleton +class RetrofitAPI @Inject constructor() { //실제 사용될 때 Retrofit 객체 생성 - val retrofitService: RetrofitService by lazy { + private val retrofitService: RetrofitService by lazy { Log.d("yeong", "Use Retrofit!") Retrofit.Builder() .baseUrl("https://dapi.kakao.com/v2/local/search/") diff --git a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index ed05a790..b0c50dac 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -7,7 +7,6 @@ import android.text.TextWatcher import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import campus.tech.kakao.map.adapter.listener.RecentAdapterListener import campus.tech.kakao.map.adapter.listener.SearchAdapterListener @@ -15,10 +14,8 @@ import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.databinding.ActivityDataSearchBinding -import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.viewModel.DBViewModel import campus.tech.kakao.map.viewModel.SearchViewModel -import campus.tech.kakao.map.viewModel.factory.SearchViewModelFactory import dagger.hilt.android.AndroidEntryPoint import androidx.activity.viewModels @@ -26,10 +23,9 @@ import androidx.activity.viewModels class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAdapterListener { private lateinit var binding: ActivityDataSearchBinding - private lateinit var searchViewModel: SearchViewModel //검색 결과 관리 //추후 계획: step2에서 수정이 있었던 부분이기 때문에, step2에서 Hilt 적용 + private val searchViewModel: SearchViewModel by viewModels() private val recentViewModel: DBViewModel by viewModels() //최근 검색어 관리 - private lateinit var searchResultRepo: SearchResultRepository //검색 결과 관리 private lateinit var searchResultDataAdapter: SearchDataAdapter //검색 결과 표시 위함 override fun onCreate(savedInstanceState: Bundle?) { @@ -37,13 +33,6 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda setBind() - //ViewModel 생성 - searchResultRepo = SearchResultRepository() - searchViewModel = ViewModelProvider( - this, - SearchViewModelFactory(searchResultRepo) - )[SearchViewModel::class.java] - //RecyclerView Layout 매니저 설정 (스크롤 방향 설정) binding.searchResulListView.layoutManager = LinearLayoutManager(this) binding.recentSearchListView.layoutManager = @@ -76,7 +65,7 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda }) } - private fun setBind(){ + private fun setBind() { binding = ActivityDataSearchBinding.inflate(layoutInflater) val view = binding.root setContentView(view) diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt index dd49c552..82805cd4 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt @@ -5,8 +5,14 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.retrofit.Document +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SearchViewModel @Inject constructor( + private val repository: SearchResultRepository +) : ViewModel() { -class SearchViewModel(private val repository: SearchResultRepository) : ViewModel() { private val _searchDataList = MutableLiveData>() val searchResults: LiveData> get() = _searchDataList From 606ac7f3c8b824982ee151f1de110c4416a69761 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:28:12 +0900 Subject: [PATCH 21/32] refactor: Remove ViewModelFactory due to Hilt implementation --- .../viewModel/factory/MapViewModelFactory.kt | 17 ----------------- .../viewModel/factory/SearchViewModelFactory.kt | 15 --------------- 2 files changed, 32 deletions(-) delete mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt delete mode 100644 app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt deleted file mode 100644 index d40bb5f7..00000000 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/MapViewModelFactory.kt +++ /dev/null @@ -1,17 +0,0 @@ -package campus.tech.kakao.map.viewModel.factory - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.repository.PreferenceRepository -import campus.tech.kakao.map.viewModel.MapViewModel -import java.lang.IllegalArgumentException - -class MapViewModelFactory(repository: PreferenceRepository): ViewModelProvider.Factory { - private val prefersRepo = repository - override fun create(modelClass: Class): T { - if(modelClass.isAssignableFrom(MapViewModel::class.java)){ - return MapViewModel(prefersRepo) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt deleted file mode 100644 index a8ee90c6..00000000 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/factory/SearchViewModelFactory.kt +++ /dev/null @@ -1,15 +0,0 @@ -package campus.tech.kakao.map.viewModel.factory - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import campus.tech.kakao.map.repository.SearchResultRepository import campus.tech.kakao.map.viewModel.SearchViewModel -import java.lang.IllegalArgumentException - -class SearchViewModelFactory(private val searchResultRepo: SearchResultRepository) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - if(modelClass.isAssignableFrom(SearchViewModel::class.java)){ - return SearchViewModel(searchResultRepo) as T - } - throw IllegalArgumentException("Unknown ViewModel class") - } -} \ No newline at end of file From fff67d0fa5852449d2b2405c4763af2cdc2b535c Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:31:16 +0900 Subject: [PATCH 22/32] Refactor: Remove unnecessary function parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기능 수정 없음 --- .../java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt | 2 +- .../tech/kakao/map/repository/SearchHistoryRepository.kt | 2 +- .../main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt index 3e783164..c4e27a9f 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt @@ -39,7 +39,7 @@ class RecentSearchAdapter( viewHolder.deleteBtn.setOnClickListener { dbViewModel.viewModelScope.launch { - dbViewModel.deleteRecentData(item.name, item.address, item.searchTime) + dbViewModel.deleteRecentData(item.name, item.address) } } diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt index 00d4a52d..a551e381 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt @@ -32,7 +32,7 @@ class SearchHistoryRepository @Inject constructor( } } - suspend fun deleteSearchData(name: String, address: String, time: Long) { + suspend fun deleteSearchData(name: String, address: String) { withContext(Dispatchers.IO) { Log.d("yeong","Repository: 여기 까지 옴") val item = searchHistoryDao.findSearchItem(name, address) diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt index 5e7d4e05..e70fe41e 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt @@ -41,9 +41,9 @@ class DBViewModel @Inject constructor( return searchHistoryDataList } - suspend fun deleteRecentData(data: String, address: String, time: Long) { + suspend fun deleteRecentData(data: String, address: String) { Log.d("yeong", "DBViewModel: 여기까지 옴") - searchHistoryRepo.deleteSearchData(data, address, time) + searchHistoryRepo.deleteSearchData(data, address) _searchHistoryDataList.value = searchHistoryRepo.getSearchHistory() } } \ No newline at end of file From 6b50b602f0d6486938720fccf4ab5c0d58699ef3 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:31:45 +0900 Subject: [PATCH 23/32] Refactor: Change variable visibility to private --- .../java/campus/tech/kakao/map/viewModel/SearchViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt index 82805cd4..82771055 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchViewModel.kt @@ -14,7 +14,7 @@ class SearchViewModel @Inject constructor( ) : ViewModel() { private val _searchDataList = MutableLiveData>() - val searchResults: LiveData> get() = _searchDataList + private val searchResults: LiveData> get() = _searchDataList fun loadResultData(searchQuery: String) { repository.loadResultMapData(searchQuery) { documents -> From 856d42c9b8518f22270d37d3bd72e157a25e7769 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:32:28 +0900 Subject: [PATCH 24/32] refactor: Remove unused import statements --- .../java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt | 1 - .../main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt | 4 ---- 2 files changed, 5 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt index 6bdc022a..48040440 100644 --- a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt +++ b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt @@ -1,7 +1,6 @@ package campus.tech.kakao.map.data.room import androidx.room.Dao -import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query diff --git a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt index e6ea5058..df4b676f 100644 --- a/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt +++ b/app/src/main/java/campus/tech/kakao/map/retrofit/RetrofitAPI.kt @@ -2,10 +2,6 @@ package campus.tech.kakao.map.retrofit import android.util.Log import campus.tech.kakao.map.BuildConfig -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent import retrofit2.Call import retrofit2.Callback import retrofit2.Response From f228c1d0fe20aa85afd253d3d9f81c40f1e70c7d Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:34:00 +0900 Subject: [PATCH 25/32] refactor: Remove unnecessary logging statements --- .../campus/tech/kakao/map/repository/SearchHistoryRepository.kt | 2 -- .../main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt | 2 -- 2 files changed, 4 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt index a551e381..2b8b1b0e 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt @@ -1,7 +1,6 @@ package campus.tech.kakao.map.repository import android.content.Context -import android.util.Log import campus.tech.kakao.map.data.room.SearchHistoryDao import campus.tech.kakao.map.data.room.SearchHistoryData import campus.tech.kakao.map.data.room.SearchHistoryDatabase @@ -34,7 +33,6 @@ class SearchHistoryRepository @Inject constructor( suspend fun deleteSearchData(name: String, address: String) { withContext(Dispatchers.IO) { - Log.d("yeong","Repository: 여기 까지 옴") val item = searchHistoryDao.findSearchItem(name, address) if (item != null) { searchHistoryDao.deleteSearchItem(name, address) diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt index e70fe41e..69d62688 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt @@ -1,6 +1,5 @@ package campus.tech.kakao.map.viewModel -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -42,7 +41,6 @@ class DBViewModel @Inject constructor( } suspend fun deleteRecentData(data: String, address: String) { - Log.d("yeong", "DBViewModel: 여기까지 옴") searchHistoryRepo.deleteSearchData(data, address) _searchHistoryDataList.value = searchHistoryRepo.getSearchHistory() } From 238a1193da8ab27059b0b84acf7186c82463abd9 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:49:21 +0900 Subject: [PATCH 26/32] =?UTF-8?q?[step1=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81]refactor:=20Rename=20DBViewModel=20to=20Sear?= =?UTF-8?q?chHistoryViewModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../campus/tech/kakao/map/adapter/RecentSearchAdapter.kt | 8 ++++---- .../campus/tech/kakao/map/adapter/SearchDataAdapter.kt | 4 ++-- .../java/campus/tech/kakao/map/view/DataSearchActivity.kt | 4 ++-- .../{DBViewModel.kt => SearchHistoryViewModel.kt} | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename app/src/main/java/campus/tech/kakao/map/viewModel/{DBViewModel.kt => SearchHistoryViewModel.kt} (96%) diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt index c4e27a9f..81f2c840 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/RecentSearchAdapter.kt @@ -10,12 +10,12 @@ import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R import campus.tech.kakao.map.data.room.SearchHistoryData import campus.tech.kakao.map.adapter.listener.RecentAdapterListener -import campus.tech.kakao.map.viewModel.DBViewModel +import campus.tech.kakao.map.viewModel.SearchHistoryViewModel import kotlinx.coroutines.launch class RecentSearchAdapter( private val searchHistoryDataList: List, - private val dbViewModel: DBViewModel, + private val searchHistoryViewModel: SearchHistoryViewModel, private val adapterListener: RecentAdapterListener ) : RecyclerView.Adapter() { @@ -38,8 +38,8 @@ class RecentSearchAdapter( viewHolder.name.text = item.name viewHolder.deleteBtn.setOnClickListener { - dbViewModel.viewModelScope.launch { - dbViewModel.deleteRecentData(item.name, item.address) + searchHistoryViewModel.viewModelScope.launch { + searchHistoryViewModel.deleteRecentData(item.name, item.address) } } diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt index f7fc3dc3..541bbe59 100644 --- a/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt +++ b/app/src/main/java/campus/tech/kakao/map/adapter/SearchDataAdapter.kt @@ -8,13 +8,13 @@ import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView import campus.tech.kakao.map.R import campus.tech.kakao.map.adapter.listener.SearchAdapterListener -import campus.tech.kakao.map.viewModel.DBViewModel +import campus.tech.kakao.map.viewModel.SearchHistoryViewModel import campus.tech.kakao.map.retrofit.Document import kotlinx.coroutines.launch class SearchDataAdapter( private var items: List, - private val recentViewModel: DBViewModel, + private val recentViewModel: SearchHistoryViewModel, private var adapterListener: SearchAdapterListener ) : RecyclerView.Adapter() { diff --git a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index b0c50dac..1d7689d6 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -14,7 +14,7 @@ import campus.tech.kakao.map.adapter.RecentSearchAdapter import campus.tech.kakao.map.adapter.SearchDataAdapter import campus.tech.kakao.map.data.LocationDataContract import campus.tech.kakao.map.databinding.ActivityDataSearchBinding -import campus.tech.kakao.map.viewModel.DBViewModel +import campus.tech.kakao.map.viewModel.SearchHistoryViewModel import campus.tech.kakao.map.viewModel.SearchViewModel import dagger.hilt.android.AndroidEntryPoint import androidx.activity.viewModels @@ -24,7 +24,7 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda private lateinit var binding: ActivityDataSearchBinding private val searchViewModel: SearchViewModel by viewModels() - private val recentViewModel: DBViewModel by viewModels() //최근 검색어 관리 + private val recentViewModel: SearchHistoryViewModel by viewModels() //최근 검색어 관리 private lateinit var searchResultDataAdapter: SearchDataAdapter //검색 결과 표시 위함 diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchHistoryViewModel.kt similarity index 96% rename from app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt rename to app/src/main/java/campus/tech/kakao/map/viewModel/SearchHistoryViewModel.kt index 69d62688..b6ce161e 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/DBViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/SearchHistoryViewModel.kt @@ -11,7 +11,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class DBViewModel @Inject constructor( +class SearchHistoryViewModel @Inject constructor( private val searchHistoryRepo: SearchHistoryRepository ) : ViewModel() { From 787f37b7d5ddef64f8609d12bae60ad8e2118c53 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 21:53:01 +0900 Subject: [PATCH 27/32] =?UTF-8?q?[step1=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81]refactor:=20Rename=20ViewModel=20variable=20?= =?UTF-8?q?for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../campus/tech/kakao/map/view/DataSearchActivity.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index 1d7689d6..ed231651 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -24,7 +24,7 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda private lateinit var binding: ActivityDataSearchBinding private val searchViewModel: SearchViewModel by viewModels() - private val recentViewModel: SearchHistoryViewModel by viewModels() //최근 검색어 관리 + private val searchHistoryViewModel: SearchHistoryViewModel by viewModels() //최근 검색어 관리 private lateinit var searchResultDataAdapter: SearchDataAdapter //검색 결과 표시 위함 @@ -39,10 +39,10 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) //Adapter 초기화 - searchResultDataAdapter = SearchDataAdapter(emptyList(), recentViewModel, this) + searchResultDataAdapter = SearchDataAdapter(emptyList(), searchHistoryViewModel, this) binding.searchResulListView.adapter = searchResultDataAdapter binding.recentSearchListView.adapter = - RecentSearchAdapter(emptyList(), recentViewModel, this) + RecentSearchAdapter(emptyList(), searchHistoryViewModel, this) resetButtonListener() //x버튼 눌러 검색 입력 필드 내용 삭제 setTextWatcher() //검색 입력 필드 텍스트 변경 리스너 @@ -59,9 +59,9 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda }) //검색 history 데이터 관찰 - recentViewModel.getRecentDataLiveData().observe(this, Observer { recentData -> + searchHistoryViewModel.getRecentDataLiveData().observe(this, Observer { recentData -> binding.recentSearchListView.adapter = - RecentSearchAdapter(recentData, recentViewModel, this) + RecentSearchAdapter(recentData, searchHistoryViewModel, this) }) } From 922cd8400333befb11fb9f80ed446cd083329d9e Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 23:23:25 +0900 Subject: [PATCH 28/32] =?UTF-8?q?[step2=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81]refactor:=20Fix=20DataBinding=20in=20BottomS?= =?UTF-8?q?heet=20to=20Display=20Location=20Information?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tech/kakao/map/view/HomeMapActivity.kt | 48 +++++++++++-------- .../tech/kakao/map/viewModel/MapViewModel.kt | 12 +++++ .../res/layout/map_detail_bottom_sheet.xml | 10 ++-- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index 36339523..c03bdd41 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -3,7 +3,7 @@ package campus.tech.kakao.map.view import android.content.Intent import android.graphics.Color import android.os.Bundle -import android.widget.TextView +import android.util.Log import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout @@ -21,13 +21,13 @@ import com.kakao.vectormap.label.LabelStyle import com.kakao.vectormap.label.LabelStyles import dagger.hilt.android.AndroidEntryPoint import androidx.activity.viewModels +import androidx.databinding.DataBindingUtil +import campus.tech.kakao.map.databinding.MapDetailBottomSheetBinding @AndroidEntryPoint class HomeMapActivity : AppCompatActivity() { private lateinit var binding: ActivityHomeMapBinding - - private lateinit var placeNameTextView: TextView - private lateinit var placeAddressTextView: TextView + private lateinit var bottomSheetBinding: MapDetailBottomSheetBinding private val mapViewModel: MapViewModel by viewModels() @@ -39,14 +39,12 @@ class HomeMapActivity : AppCompatActivity() { enableEdgeToEdge() setBinding() + setViewModel() - val name = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() - val address = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() - val latitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() - val longitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() - - placeNameTextView = findViewById(R.id.placeName) - placeAddressTextView = findViewById(R.id.placeAddress) + val placeName = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() + val placeAddress = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() + val placeLatitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() + val placeLongitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() bottomBehavior = BottomSheetBehavior.from(bottomSheet) @@ -63,7 +61,7 @@ class HomeMapActivity : AppCompatActivity() { override fun onMapReady(p0: KakaoMap) { // 라벨 생성 - if (latitude != null && longitude != null) { + if (placeLatitude != null && placeLongitude != null) { p0.labelManager val style = p0.labelManager?.addLabelStyles( @@ -75,8 +73,8 @@ class HomeMapActivity : AppCompatActivity() { ) ) val options = - LabelOptions.from(LatLng.from(latitude, longitude)).setStyles(style) - .setTexts(name) + LabelOptions.from(LatLng.from(placeLatitude, placeLongitude)).setStyles(style) + .setTexts(placeName) val layer = p0.labelManager?.layer layer?.addLabel(options) } @@ -91,8 +89,8 @@ class HomeMapActivity : AppCompatActivity() { mapViewModel.getLocation(LocationDataContract.LOCATION_LONGITUDE, null) .toDoubleOrNull() - return if (latitude != null && longitude != null) { - LatLng.from(latitude, longitude) + return if (placeLatitude != null && placeLongitude != null) { + LatLng.from(placeLatitude, placeLongitude) } else if (savedLatitude != null && savedLongitude != null) { LatLng.from(savedLatitude, savedLongitude) } else { @@ -101,10 +99,10 @@ class HomeMapActivity : AppCompatActivity() { } }) - if (latitude != null && longitude != null) { - placeNameTextView.text = name - placeAddressTextView.text = address + if (placeLatitude != null && placeLongitude != null) { bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED + mapViewModel.updateInfo(placeName,placeAddress) + Log.d("yeong", mapViewModel.placeInfoList.value.toString()) } else { bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN } @@ -143,5 +141,17 @@ class HomeMapActivity : AppCompatActivity() { binding = ActivityHomeMapBinding.inflate(layoutInflater) val view = binding.root setContentView(view) + + bottomSheetBinding = DataBindingUtil.inflate( + layoutInflater, + R.layout.map_detail_bottom_sheet, + findViewById(R.id.bottomSheet), + true + ) + bottomSheetBinding.lifecycleOwner = this + } + + private fun setViewModel(){ + bottomSheetBinding.viewModel = mapViewModel } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt index f06373eb..8942e5e3 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt @@ -1,5 +1,7 @@ package campus.tech.kakao.map.viewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import campus.tech.kakao.map.repository.PreferenceRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -10,6 +12,16 @@ class MapViewModel @Inject constructor( private val prefersRepo: PreferenceRepository ) : ViewModel() { + private val _placeInfoList = MutableLiveData>() + val placeInfoList: LiveData> get() = _placeInfoList + init { + _placeInfoList.value = listOf("NONE","NONE") + } + + fun updateInfo(name: String, address: String){ + _placeInfoList.value = listOf(name,address) + } + fun saveLocation(locationKey: String, data: String) { prefersRepo.setString(locationKey, data) } diff --git a/app/src/main/res/layout/map_detail_bottom_sheet.xml b/app/src/main/res/layout/map_detail_bottom_sheet.xml index cf983722..494c8a04 100644 --- a/app/src/main/res/layout/map_detail_bottom_sheet.xml +++ b/app/src/main/res/layout/map_detail_bottom_sheet.xml @@ -4,8 +4,8 @@ + name="viewModel" + type="campus.tech.kakao.map.viewModel.MapViewModel" /> + app:layout_constraintTop_toTopOf="parent" + android:text="@{viewModel.placeInfoList[0]}"/> + app:layout_constraintTop_toBottomOf="@id/placeName" + android:text="@{viewModel.placeInfoList[1]}"/> From ffcf8cc495afe0af17963784507070bca688a612 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 23:26:16 +0900 Subject: [PATCH 29/32] style: Remove debug log statements from previous commit --- app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index c03bdd41..46dca208 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -3,7 +3,6 @@ package campus.tech.kakao.map.view import android.content.Intent import android.graphics.Color import android.os.Bundle -import android.util.Log import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout @@ -102,7 +101,6 @@ class HomeMapActivity : AppCompatActivity() { if (placeLatitude != null && placeLongitude != null) { bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED mapViewModel.updateInfo(placeName,placeAddress) - Log.d("yeong", mapViewModel.placeInfoList.value.toString()) } else { bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN } From 9479cda0051dcb85d33289c96a82094a9d6a5074 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 23:30:37 +0900 Subject: [PATCH 30/32] style: apply code formatting changes --- .../campus/tech/kakao/map/view/HomeMapActivity.kt | 15 +++++++++------ .../tech/kakao/map/viewModel/MapViewModel.kt | 7 ++++--- .../main/res/layout/map_detail_bottom_sheet.xml | 11 ++++++----- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt index 46dca208..f5679adc 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/HomeMapActivity.kt @@ -42,8 +42,10 @@ class HomeMapActivity : AppCompatActivity() { val placeName = intent.getStringExtra(LocationDataContract.LOCATION_NAME).toString() val placeAddress = intent.getStringExtra(LocationDataContract.LOCATION_ADDRESS).toString() - val placeLatitude = intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() - val placeLongitude = intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() + val placeLatitude = + intent.getStringExtra(LocationDataContract.LOCATION_LATITUDE)?.toDouble() + val placeLongitude = + intent.getStringExtra(LocationDataContract.LOCATION_LONGITUDE)?.toDouble() bottomBehavior = BottomSheetBehavior.from(bottomSheet) @@ -72,7 +74,8 @@ class HomeMapActivity : AppCompatActivity() { ) ) val options = - LabelOptions.from(LatLng.from(placeLatitude, placeLongitude)).setStyles(style) + LabelOptions.from(LatLng.from(placeLatitude, placeLongitude)) + .setStyles(style) .setTexts(placeName) val layer = p0.labelManager?.layer layer?.addLabel(options) @@ -100,7 +103,7 @@ class HomeMapActivity : AppCompatActivity() { if (placeLatitude != null && placeLongitude != null) { bottomBehavior.state = BottomSheetBehavior.STATE_EXPANDED - mapViewModel.updateInfo(placeName,placeAddress) + mapViewModel.updateInfo(placeName, placeAddress) } else { bottomBehavior.state = BottomSheetBehavior.STATE_HIDDEN } @@ -135,7 +138,7 @@ class HomeMapActivity : AppCompatActivity() { startActivity(intentError) } - private fun setBinding(){ + private fun setBinding() { binding = ActivityHomeMapBinding.inflate(layoutInflater) val view = binding.root setContentView(view) @@ -149,7 +152,7 @@ class HomeMapActivity : AppCompatActivity() { bottomSheetBinding.lifecycleOwner = this } - private fun setViewModel(){ + private fun setViewModel() { bottomSheetBinding.viewModel = mapViewModel } } \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt index 8942e5e3..fadc0f16 100644 --- a/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt +++ b/app/src/main/java/campus/tech/kakao/map/viewModel/MapViewModel.kt @@ -14,12 +14,13 @@ class MapViewModel @Inject constructor( private val _placeInfoList = MutableLiveData>() val placeInfoList: LiveData> get() = _placeInfoList + init { - _placeInfoList.value = listOf("NONE","NONE") + _placeInfoList.value = listOf("NONE", "NONE") } - fun updateInfo(name: String, address: String){ - _placeInfoList.value = listOf(name,address) + fun updateInfo(name: String, address: String) { + _placeInfoList.value = listOf(name, address) } fun saveLocation(locationKey: String, data: String) { diff --git a/app/src/main/res/layout/map_detail_bottom_sheet.xml b/app/src/main/res/layout/map_detail_bottom_sheet.xml index 494c8a04..da104982 100644 --- a/app/src/main/res/layout/map_detail_bottom_sheet.xml +++ b/app/src/main/res/layout/map_detail_bottom_sheet.xml @@ -1,8 +1,9 @@ - + @@ -23,11 +24,11 @@ android:layout_marginStart="20dp" android:layout_marginTop="15dp" android:layout_marginBottom="10dp" + android:text="@{viewModel.placeInfoList[0]}" android:textSize="20sp" app:layout_constraintBottom_toTopOf="@id/placeAddress" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - android:text="@{viewModel.placeInfoList[0]}"/> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@id/placeName" /> From ef760ac03ab7b8ae55ce52678b99989b9bae7c96 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Mon, 29 Jul 2024 23:46:54 +0900 Subject: [PATCH 31/32] =?UTF-8?q?[Step2=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81]refactor:=20Inject=20SearchHistoryDao=20dire?= =?UTF-8?q?ctly=20into=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kakao/map/data/room/DatabaseModule.kt | 25 +++++++++++++++++++ .../kakao/map/data/room/SearchHistoryDao.kt | 2 ++ .../map/repository/SearchHistoryRepository.kt | 9 +------ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/campus/tech/kakao/map/data/room/DatabaseModule.kt diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/DatabaseModule.kt b/app/src/main/java/campus/tech/kakao/map/data/room/DatabaseModule.kt new file mode 100644 index 00000000..49c8bb0d --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/data/room/DatabaseModule.kt @@ -0,0 +1,25 @@ +package campus.tech.kakao.map.data.room + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton +import android.content.Context + +@Module +@InstallIn(SingletonComponent::class) +object DatabaseModule { + + @Provides + @Singleton + fun provideSearchHistoryDatabase(@ApplicationContext context: Context): SearchHistoryDatabase { + return SearchHistoryDatabase.getDatabase(context) + } + + @Provides + fun provideSearchHistoryDao(database: SearchHistoryDatabase): SearchHistoryDao { + return database.searchHistoryDao() + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt index 48040440..2aa9e574 100644 --- a/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt +++ b/app/src/main/java/campus/tech/kakao/map/data/room/SearchHistoryDao.kt @@ -4,7 +4,9 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import javax.inject.Singleton +@Singleton @Dao interface SearchHistoryDao { @Query("SELECT * FROM searchHistory ORDER BY searchTime DESC") diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt index 2b8b1b0e..f4561c60 100644 --- a/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt +++ b/app/src/main/java/campus/tech/kakao/map/repository/SearchHistoryRepository.kt @@ -1,10 +1,7 @@ package campus.tech.kakao.map.repository -import android.content.Context import campus.tech.kakao.map.data.room.SearchHistoryDao import campus.tech.kakao.map.data.room.SearchHistoryData -import campus.tech.kakao.map.data.room.SearchHistoryDatabase -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import javax.inject.Inject @@ -12,12 +9,8 @@ import javax.inject.Singleton @Singleton class SearchHistoryRepository @Inject constructor( - @ApplicationContext context: Context + private val searchHistoryDao: SearchHistoryDao ) { - - private val searchHistoryDao: SearchHistoryDao = - SearchHistoryDatabase.getDatabase(context).searchHistoryDao() - suspend fun getSearchHistory(): List { return withContext(Dispatchers.IO) { searchHistoryDao.getSearchHistory() From 49556a40ca1bf6ca02e40936512e3f4e0c9b4147 Mon Sep 17 00:00:00 2001 From: yb0x00 Date: Tue, 30 Jul 2024 14:59:12 +0900 Subject: [PATCH 32/32] refactor: Rename setBind function to setBinding for consistency --- .../java/campus/tech/kakao/map/view/DataSearchActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt index ed231651..13c82349 100644 --- a/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt +++ b/app/src/main/java/campus/tech/kakao/map/view/DataSearchActivity.kt @@ -31,7 +31,7 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setBind() + setBinding() //RecyclerView Layout 매니저 설정 (스크롤 방향 설정) binding.searchResulListView.layoutManager = LinearLayoutManager(this) @@ -65,7 +65,7 @@ class DataSearchActivity : AppCompatActivity(), RecentAdapterListener, SearchAda }) } - private fun setBind() { + private fun setBinding() { binding = ActivityDataSearchBinding.inflate(layoutInflater) val view = binding.root setContentView(view)