diff --git a/README.md b/README.md index df2a6477..3eb34c00 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ -# android-map-keyword +# 2주차 - android-map-keyword +## step1 구현할 기능 목록 + +**UI 관련 기능** +- [x] 검색어를 입력할 수 있는 칸 구현 +- [x] 검색 결과를 표시할 수 있는 칸 구현 +- [x] 저장된 검색 결과를 표시할 수 있는 칸 구현 + +**DB 관련 기능** +- [x] 장소의 이름, 장소의 위치. 장소 카테고리를 저장할 수 있는 데이터베이스 구현 + +--------------------------- +## step2 구현할 기능 목록 + + +**검색 관련 기능** +- [x] 검색어를 입력하면 검색 결과 목록을 스크롤이 가능하도록 띄우는 기능 +- [x] X를 누르면 입력한 검색어를 삭제하는 기능 + +**저장 관련 기능** +- [x] 검색 결과 목록중 하나를 클릭하면 저장하는 기능 +- [x] 저장된 목록을 검색창 밑에서 가로 스크롤이 가능하도록 띄우는 기능 +- [x] 저장된 목록중 X를 누르면 저장된 목록을 삭제하는 기능 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6bca2f54..a668b40d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ android:theme="@style/Theme.Map" tools:targetApi="31"> 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/adapter/PlaceViewAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/PlaceViewAdapter.kt new file mode 100644 index 00000000..d1fc3191 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/adapter/PlaceViewAdapter.kt @@ -0,0 +1,49 @@ +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.TextView +import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.view.OnClickPlaceListener +import campus.tech.kakao.map.R +import campus.tech.kakao.map.model.Place + +class PlaceViewAdapter( + val placeList: LiveData>, + val inflater: LayoutInflater, + val listener: OnClickPlaceListener +) : RecyclerView.Adapter() { + + inner class PlaceViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val name = itemView.findViewById(R.id.place_name) + val location = itemView.findViewById(R.id.place_location) + val category = itemView.findViewById(R.id.place_category) + + init { + itemView.setOnClickListener { + val position = absoluteAdapterPosition + Log.d("testt", "콜백함수 호출") + placeList.value?.get(position)?.let { listener.savePlace(it) } + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaceViewHolder { + val view = inflater.inflate(R.layout.place_item, parent, false) + Log.d("testt", "검색 결과 뷰 생성") + return PlaceViewHolder(view) + } + + override fun onBindViewHolder(holder: PlaceViewHolder, position: Int) { + holder.name.text = placeList.value?.get(position)?.name ?: "" + holder.location.text = placeList.value?.get(position)?.location ?: "" + holder.category.text = placeList.value?.get(position)?.category ?: "" + } + + override fun getItemCount(): Int { + return placeList.value?.size ?: 0 + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/adapter/SavedPlaceViewAdapter.kt b/app/src/main/java/campus/tech/kakao/map/adapter/SavedPlaceViewAdapter.kt new file mode 100644 index 00000000..8ae34ed1 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/adapter/SavedPlaceViewAdapter.kt @@ -0,0 +1,48 @@ +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.ImageView +import android.widget.TextView +import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.view.OnClickSavedPlaceListener +import campus.tech.kakao.map.R +import campus.tech.kakao.map.model.SavedPlace + +class SavedPlaceViewAdapter( + val savedPlaceList: LiveData>, + val inflater: LayoutInflater, + val listener: OnClickSavedPlaceListener +) : RecyclerView.Adapter() { + + inner class SavedPlaceViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val name = itemView.findViewById(R.id.saved_place_name) + val deleteButton = itemView.findViewById(R.id.button_saved_delete) + + init { + deleteButton.setOnClickListener { + val position = absoluteAdapterPosition + Log.d("testt", "삭제 콜백함수 호출") + savedPlaceList.value?.get(position)?.let { listener.deleteSavedPlace(it, position) } + } + } + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SavedPlaceViewHolder { + val view = inflater.inflate(R.layout.saved_place_item, parent, false) + Log.d("testt", "저장된 장소를 띄우는 뷰 홀더 생성") + return SavedPlaceViewHolder(view) + } + + override fun onBindViewHolder(holder: SavedPlaceViewHolder, position: Int) { + holder.name.text = savedPlaceList.value?.get(position)?.name ?: "" + } + + override fun getItemCount(): Int { + return savedPlaceList.value?.size ?: 0 + } +} diff --git a/app/src/main/java/campus/tech/kakao/map/db/PlaceContract.kt b/app/src/main/java/campus/tech/kakao/map/db/PlaceContract.kt new file mode 100644 index 00000000..95147ac8 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/db/PlaceContract.kt @@ -0,0 +1,17 @@ +package campus.tech.kakao.map.db + +import android.provider.BaseColumns + +object PlaceContract{ + object PlaceEntry : BaseColumns { + const val TABLE_NAME = "PLACE" + const val COLUMN_NAME = "NAME" + const val COLUMN_LOCATION = "LOCATION" + const val COLUMN_CATEGORY = "CATEGORY" + } + + object SavedPlaceEntry : BaseColumns{ + const val TABLE_NAME = "SAVED_PLACE" + const val COLUMN_NAME = "SAVED_NAME" + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/db/PlaceDBHelper.kt b/app/src/main/java/campus/tech/kakao/map/db/PlaceDBHelper.kt new file mode 100644 index 00000000..765f94f7 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/db/PlaceDBHelper.kt @@ -0,0 +1,92 @@ +package campus.tech.kakao.map.db + +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase +import android.database.sqlite.SQLiteOpenHelper +import android.util.Log + + +class PlaceDBHelper(context: Context) : SQLiteOpenHelper(context, "place.db", null, 2) { + override fun onCreate(db: SQLiteDatabase?) { + db?.execSQL( + "CREATE TABLE " + + "${PlaceContract.PlaceEntry.TABLE_NAME}( " + + " ${PlaceContract.PlaceEntry.COLUMN_NAME} varchar(60) not null ," + + " ${PlaceContract.PlaceEntry.COLUMN_LOCATION} varchar(255) not null, " + + " ${PlaceContract.PlaceEntry.COLUMN_CATEGORY} varchar(30) );" + ) + + db?.execSQL( + "CREATE TABLE " + + "${PlaceContract.SavedPlaceEntry.TABLE_NAME}( " + + " ${PlaceContract.SavedPlaceEntry.COLUMN_NAME} varchar(60) not null);" + ) + } + + override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { + db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.PlaceEntry.TABLE_NAME};") + db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.SavedPlaceEntry.TABLE_NAME};") + onCreate(db) + } + + fun insertDummyData() { + val name = "카페" + val category = "카페" + val location = "서울 농기구 고길동" + for (i in 1..10) { + insertPlaceData(name + i, location + i, category) + } + readPlaceData() + } + + fun insertPlaceData(name: String, location: String, category: String) { + val db = this.writableDatabase + val values = ContentValues().apply { + put(PlaceContract.PlaceEntry.COLUMN_NAME, name) + put(PlaceContract.PlaceEntry.COLUMN_LOCATION, location) + put(PlaceContract.PlaceEntry.COLUMN_CATEGORY, category) + } + db.insert(PlaceContract.PlaceEntry.TABLE_NAME, null, values) + } + + fun insertSavedPlaceData(name: String) { + val db = this.writableDatabase + val values = ContentValues().apply { + put(PlaceContract.SavedPlaceEntry.COLUMN_NAME, name) + } + db.insert(PlaceContract.SavedPlaceEntry.TABLE_NAME, null, values) + } + + fun readPlaceData(): Cursor { + val rDb = this.readableDatabase + return rDb.rawQuery("SELECT * FROM ${PlaceContract.PlaceEntry.TABLE_NAME};", null) + } + + fun readPlaceDataWithSamedCategory(category: String): Cursor { + val rDb = this.readableDatabase + return rDb.rawQuery( + "SELECT * FROM ${PlaceContract.PlaceEntry.TABLE_NAME} WHERE ${PlaceContract.PlaceEntry.COLUMN_CATEGORY} = '${category}';", + null + ) + } + + fun readSavedPlaceData(): Cursor { + val rDb = this.readableDatabase + return rDb.rawQuery("SELECT * FROM ${PlaceContract.SavedPlaceEntry.TABLE_NAME};", null) + } + + fun readSavedPlaceDataWithSamedName(name: String): Cursor { + val rDb = this.readableDatabase + return rDb.rawQuery( + "SELECT * FROM ${PlaceContract.SavedPlaceEntry.TABLE_NAME} WHERE ${PlaceContract.SavedPlaceEntry.COLUMN_NAME} = '${name}';", + null + ) + } + + fun deleteSavedPlace(name: String) { + val db = this.writableDatabase + db.delete(PlaceContract.SavedPlaceEntry.TABLE_NAME, "${PlaceContract.SavedPlaceEntry.COLUMN_NAME} = ?", arrayOf(name)) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/model/Place.kt b/app/src/main/java/campus/tech/kakao/map/model/Place.kt new file mode 100644 index 00000000..82df63f2 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/model/Place.kt @@ -0,0 +1,7 @@ +package campus.tech.kakao.map.model + +data class Place( + val name : String, + val location : String, + val category : String +) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/model/SavedPlace.kt b/app/src/main/java/campus/tech/kakao/map/model/SavedPlace.kt new file mode 100644 index 00000000..be8f2799 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/model/SavedPlace.kt @@ -0,0 +1,5 @@ +package campus.tech.kakao.map.model + +data class SavedPlace( + val name: String +) \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/repository/PlaceRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/PlaceRepository.kt new file mode 100644 index 00000000..991451e3 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/repository/PlaceRepository.kt @@ -0,0 +1,61 @@ +package campus.tech.kakao.map.repository + +import android.util.Log +import campus.tech.kakao.map.db.PlaceContract +import campus.tech.kakao.map.db.PlaceDBHelper +import campus.tech.kakao.map.model.Place + +class PlaceRepository (val dbHelper: PlaceDBHelper){ + fun getAllPlace() : MutableList{ + val cursor = dbHelper.readPlaceData() + val placeList = mutableListOf() + + while (cursor.moveToNext()) { + val place = Place( + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_NAME) + ), + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_LOCATION) + ), + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_CATEGORY) + ) + ) + Log.d("readData", "이름 = ${place.name}, 위치 = ${place.location}, 분류 = ${place.category}") + placeList.add(place) + } + + cursor.close() + return placeList + } + + fun writePlace(place: Place){ + dbHelper.insertPlaceData(place.name, place.location, place.category) + } + + fun getPlaceWithCategory(category : String): MutableList{ + val cursor = dbHelper.readPlaceDataWithSamedCategory(category) + val placeList = mutableListOf() + + while (cursor.moveToNext()) { + val place = Place( + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_NAME) + ), + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_LOCATION) + ), + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.PlaceEntry.COLUMN_CATEGORY) + ) + ) + Log.d("readData", "이름 = ${place.name}, 위치 = ${place.location}, 분류 = ${place.category}") + placeList.add(place) + } + + + cursor.close() + return placeList + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/repository/SavedPlaceRepository.kt b/app/src/main/java/campus/tech/kakao/map/repository/SavedPlaceRepository.kt new file mode 100644 index 00000000..c54cb81a --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/repository/SavedPlaceRepository.kt @@ -0,0 +1,43 @@ +package campus.tech.kakao.map.repository + +import android.util.Log +import campus.tech.kakao.map.db.PlaceContract +import campus.tech.kakao.map.db.PlaceDBHelper +import campus.tech.kakao.map.model.Place +import campus.tech.kakao.map.model.SavedPlace + +class SavedPlaceRepository (val dbHelper: PlaceDBHelper){ + fun getAllSavedPlace() : MutableList{ + val cursor = dbHelper.readSavedPlaceData() + val placeList = mutableListOf() + + while (cursor.moveToNext()) { + val place = SavedPlace( + cursor.getString( + cursor.getColumnIndexOrThrow(PlaceContract.SavedPlaceEntry.COLUMN_NAME) + ) + ) + Log.d("readData", "이름 = ${place.name}") + placeList.add(place) + } + + cursor.close() + return placeList + } + + fun writePlace(place: Place){ + val cursor = dbHelper.readSavedPlaceDataWithSamedName(place.name) + if (cursor.moveToFirst()) { + Log.d("testt", "데이터 중복") + // 입력의 시간순대로 정렬되기 떄문에 레코드 삭제후 다시 집어넣기 + dbHelper.deleteSavedPlace(place.name) + dbHelper.insertSavedPlaceData(place.name) + } else { + dbHelper.insertSavedPlaceData(place.name) + } + } + + fun deleteSavedPlace(savedPlace: SavedPlace){ + dbHelper.deleteSavedPlace(savedPlace.name) + } +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/view/ClickListener.kt b/app/src/main/java/campus/tech/kakao/map/view/ClickListener.kt new file mode 100644 index 00000000..b42e2ae9 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/view/ClickListener.kt @@ -0,0 +1,12 @@ +package campus.tech.kakao.map.view + +import campus.tech.kakao.map.model.Place +import campus.tech.kakao.map.model.SavedPlace + +interface OnClickPlaceListener { + fun savePlace(place: Place) +} + +interface OnClickSavedPlaceListener { + fun deleteSavedPlace(savedPlace: SavedPlace, position: Int) +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/view/MainActivity.kt b/app/src/main/java/campus/tech/kakao/map/view/MainActivity.kt new file mode 100644 index 00000000..ba3e60ba --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/view/MainActivity.kt @@ -0,0 +1,145 @@ +package campus.tech.kakao.map.view + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.widget.EditText +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import campus.tech.kakao.map.R +import campus.tech.kakao.map.adapter.PlaceViewAdapter +import campus.tech.kakao.map.adapter.SavedPlaceViewAdapter +import campus.tech.kakao.map.db.PlaceDBHelper +import campus.tech.kakao.map.model.Place +import campus.tech.kakao.map.model.SavedPlace +import campus.tech.kakao.map.repository.PlaceRepository +import campus.tech.kakao.map.repository.SavedPlaceRepository +import campus.tech.kakao.map.viewmodel.MainActivityViewModel +import campus.tech.kakao.map.viewmodel.ViewModelFactory + + +class MainActivity : AppCompatActivity(), OnClickPlaceListener, OnClickSavedPlaceListener { + lateinit var noResultText: TextView + lateinit var inputSearchField: EditText + lateinit var viewModel: MainActivityViewModel + lateinit var savedPlaceRecyclerView: RecyclerView + lateinit var searchRecyclerView: RecyclerView + lateinit var dbHelper: PlaceDBHelper + lateinit var placeRepository: PlaceRepository + lateinit var savedPlaceRepository: SavedPlaceRepository + lateinit var searchDeleteButton: ImageView + lateinit var savedPlaceRecyclerViewAdapter: SavedPlaceViewAdapter + lateinit var searchRecyclerViewAdapter: PlaceViewAdapter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + initVar() + initListeners() + initRecyclerViews() + + Log.d("testt", viewModel.place.toString()) + + viewModel.place.observe(this, Observer { + Log.d("readData", "검색창 결과 변경 감지") + val place = viewModel.place + searchRecyclerViewAdapter.notifyDataSetChanged() + if (place.value?.isEmpty() == true) noResultText.visibility = View.VISIBLE + else noResultText.visibility = View.INVISIBLE + }) + + viewModel.savedPlace.observe(this, Observer { + Log.d("readData", "저장된 장소들 변경 감지") + val savedPlace = viewModel.savedPlace + savedPlaceRecyclerViewAdapter.notifyDataSetChanged() + if (savedPlace.value?.isEmpty() == true) savedPlaceRecyclerView.visibility = View.GONE + else savedPlaceRecyclerView.visibility = View.VISIBLE + }) + } + + override fun deleteSavedPlace(savedPlace: SavedPlace, position: Int) { + Log.d("testt", "삭제 콜백함수 처리") + viewModel.deleteSavedPlace(savedPlace) + } + + override fun savePlace(place: Place) { + Log.d("testt", "콜백함수 처리") + viewModel.savePlace(place) + } + + fun initVar() { + noResultText = findViewById(R.id.no_search_result) + searchRecyclerView = findViewById(R.id.search_result_recyclerView) + inputSearchField = findViewById(R.id.input_search_field) + savedPlaceRecyclerView = findViewById(R.id.saved_search_recyclerView) + dbHelper = PlaceDBHelper(this) + placeRepository = PlaceRepository(dbHelper) + savedPlaceRepository = SavedPlaceRepository(dbHelper) + searchDeleteButton = findViewById(R.id.button_X) + viewModel = + ViewModelProvider( + this, + ViewModelFactory(placeRepository, savedPlaceRepository) + )[MainActivityViewModel::class.java] + } + + fun initListeners() { + initDeleteButtonListener() + initInputFieldListener() + } + + fun initDeleteButtonListener(){ + searchDeleteButton.setOnClickListener { + inputSearchField.setText("") + inputSearchField.clearFocus() + } + } + + fun initInputFieldListener(){ + inputSearchField.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + } + + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { + } + + override fun afterTextChanged(searchText: Editable?) { + val text = searchText.toString() + // 검색어를 입력할 때마다 place의 값이 바뀌어 notify가 계속 호출되는 문제? + viewModel.getPlaceWithCategory(text) + } + }) + } + + fun initRecyclerViews() { + initSearchRecyclerView() + initSavedPlaceRecyclerView() + } + + fun initSearchRecyclerView() { + searchRecyclerViewAdapter = PlaceViewAdapter(viewModel.place, LayoutInflater.from(this), this) + searchRecyclerView.layoutManager = LinearLayoutManager(this) + searchRecyclerView.adapter = searchRecyclerViewAdapter + } + + fun initSavedPlaceRecyclerView() { + savedPlaceRecyclerViewAdapter = + SavedPlaceViewAdapter(viewModel.savedPlace, LayoutInflater.from(this), this) + savedPlaceRecyclerView.layoutManager = + LinearLayoutManager(this, RecyclerView.HORIZONTAL, false) + savedPlaceRecyclerView.adapter = savedPlaceRecyclerViewAdapter + } +} + + + + + diff --git a/app/src/main/java/campus/tech/kakao/map/viewmodel/MainActivityViewModel.kt b/app/src/main/java/campus/tech/kakao/map/viewmodel/MainActivityViewModel.kt new file mode 100644 index 00000000..cfaaf5c8 --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewmodel/MainActivityViewModel.kt @@ -0,0 +1,46 @@ +package campus.tech.kakao.map.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import campus.tech.kakao.map.model.Place +import campus.tech.kakao.map.model.SavedPlace +import campus.tech.kakao.map.repository.PlaceRepository +import campus.tech.kakao.map.repository.SavedPlaceRepository +import java.util.Locale.Category + +class MainActivityViewModel( + private val placeRepository: PlaceRepository, + private val savedPlaceRepository: SavedPlaceRepository +) : ViewModel() { + private val _place = MutableLiveData>() + private val _savedPlace = MutableLiveData>() + val place: LiveData> get() = _place + val savedPlace: LiveData> get() = _savedPlace + init{ + getSavedPlace() + } + fun getPlace() { + _place.postValue(placeRepository.getAllPlace()) + } + + fun getPlaceWithCategory(category: String) { + _place.postValue(placeRepository.getPlaceWithCategory(category)) + } + + fun getSavedPlace() { + _savedPlace.postValue(savedPlaceRepository.getAllSavedPlace()) + } + + fun savePlace(place: Place) { + savedPlaceRepository.writePlace(place) + getSavedPlace() + } + + fun deleteSavedPlace(savedPlace: SavedPlace){ + savedPlaceRepository.deleteSavedPlace(savedPlace) + getSavedPlace() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/campus/tech/kakao/map/viewmodel/ViewModelFactory.kt b/app/src/main/java/campus/tech/kakao/map/viewmodel/ViewModelFactory.kt new file mode 100644 index 00000000..22a2ff2d --- /dev/null +++ b/app/src/main/java/campus/tech/kakao/map/viewmodel/ViewModelFactory.kt @@ -0,0 +1,18 @@ +package campus.tech.kakao.map.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import campus.tech.kakao.map.repository.PlaceRepository +import campus.tech.kakao.map.repository.SavedPlaceRepository + +class ViewModelFactory( + private val placeRepository: PlaceRepository, + private val savedPlaceRepository: SavedPlaceRepository +) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(MainActivityViewModel::class.java)) { + return MainActivityViewModel(placeRepository, savedPlaceRepository) as T + } + throw IllegalArgumentException("unKnown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 24d17df2..9710b75c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,17 +3,67 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" + android:focusable="true" + android:focusableInTouchMode="true" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".view.MainActivity"> + + + + + + + + app:layout_constraintEnd_toEndOf="parent" + android:text="@string/no_search_result" + android:textSize="18sp" + android:textColor="#737373" + /> diff --git a/app/src/main/res/layout/place_item.xml b/app/src/main/res/layout/place_item.xml new file mode 100644 index 00000000..94f5b65a --- /dev/null +++ b/app/src/main/res/layout/place_item.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/saved_place_item.xml b/app/src/main/res/layout/saved_place_item.xml new file mode 100644 index 00000000..59b85bf7 --- /dev/null +++ b/app/src/main/res/layout/saved_place_item.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 768b058a..f1b5bf4d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -2,4 +2,5 @@ #FF000000 #FFFFFFFF + #7C7C7C diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5ba5b9c..290224da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ Map + 검색어를 입력해 주세요. + 검색 결과가 없습니다. \ No newline at end of file