-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bbf77e9
commit f7ac3aa
Showing
41 changed files
with
702 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package campus.tech.kakao.map | ||
|
||
object Constants { | ||
const val SEARCH_HISTORY_KEY = "searchHistory" | ||
const val PREFERENCE_NAME = "preference_name" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.content.Context | ||
import android.database.sqlite.SQLiteDatabase | ||
import android.database.sqlite.SQLiteOpenHelper | ||
|
||
class DBHelper (context: Context): SQLiteOpenHelper(context, "place.db", null, 1) { | ||
override fun onCreate(db: SQLiteDatabase?) { | ||
db?.execSQL( | ||
"CREATE TABLE IF NOT EXISTS ${PlaceContract.TABLE_NAME} ("+ | ||
"${PlaceContract.TABLE_COLUMN_NAME} VARCHAR(30) NOT NULL,"+ | ||
"${PlaceContract.TABLE_COLUMN_ADDRESS} VARCHAR(50) NOT NULL,"+ | ||
"${PlaceContract.TABLE_COLUMN_CATEGORY} VARCHAR(30) NOT NULL"+ | ||
");" | ||
) | ||
insertDummyData(db) | ||
} | ||
|
||
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { | ||
db?.execSQL("DROP TABLE IF EXISTS ${PlaceContract.TABLE_NAME}") | ||
onCreate(db) | ||
} | ||
|
||
fun insert(db: SQLiteDatabase, place: Place) { | ||
val sql = " INSERT INTO " + | ||
"${PlaceContract.TABLE_NAME}("+ | ||
"${PlaceContract.TABLE_COLUMN_NAME}, ${PlaceContract.TABLE_COLUMN_ADDRESS}, ${PlaceContract.TABLE_COLUMN_CATEGORY})"+ | ||
" VALUES(${place.name}, ${place.address}, ${place.category});" | ||
|
||
db.execSQL(sql) | ||
} | ||
|
||
fun select(db: SQLiteDatabase, name:String, address: String, category: String) : String? { | ||
return null | ||
} | ||
|
||
private fun insertDummyData(db: SQLiteDatabase?) { | ||
db?.let { | ||
val categories = listOf("카페", "약국", "식당") | ||
val baseAddress = "서울 성동구 성수동" | ||
|
||
categories.forEach { category -> | ||
for (i in 1..15) { | ||
val name = "$category $i" | ||
val address = "$baseAddress $i" | ||
val sql = "INSERT INTO ${PlaceContract.TABLE_NAME} (" + | ||
"${PlaceContract.TABLE_COLUMN_NAME}, ${PlaceContract.TABLE_COLUMN_ADDRESS}, ${PlaceContract.TABLE_COLUMN_CATEGORY}) " + | ||
"VALUES ('$name', '$address', '$category');" | ||
it.execSQL(sql) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,118 @@ | ||
package campus.tech.kakao.map | ||
|
||
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 androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.lifecycle.Observer | ||
import androidx.recyclerview.widget.LinearLayoutManager | ||
import campus.tech.kakao.map.databinding.ActivityMainBinding | ||
|
||
class MainActivity : AppCompatActivity() { | ||
private val viewModel: MainViewModel by viewModels { | ||
ViewModelFactory(applicationContext) | ||
} | ||
|
||
private val placeAdapter: PlaceAdapter by lazy { | ||
PlaceAdapter(placeList, | ||
LayoutInflater.from(this@MainActivity), | ||
object : | ||
PlaceAdapter.OnItemClickListener { | ||
override fun onItemClick(position: Int) { | ||
val item = placeAdapter.getItem(position) | ||
val searchHistory = SearchHistory(item.name) | ||
viewModel.saveSearchHistory(searchHistory) | ||
Log.d("실행", "저장") | ||
} | ||
} | ||
) | ||
} | ||
|
||
private val historyAdapter: HistoryAdapter by lazy { | ||
HistoryAdapter( | ||
viewModel.searchHistoryList.value ?: emptyList(), | ||
LayoutInflater.from(this@MainActivity), | ||
object : HistoryAdapter.OnItemClickListener { | ||
override fun onItemClick(position: Int) { | ||
val item = viewModel.searchHistoryList.value?.get(position) | ||
if (item != null) { | ||
mainBinding.search.setText(item.searchHistory) | ||
Log.d("실행", "검색창") | ||
} | ||
} | ||
override fun onXMarkClick(position: Int) { | ||
viewModel.deleteSearchHistory(position) | ||
Log.d("실행", "삭제") | ||
} | ||
} | ||
) | ||
} | ||
|
||
private lateinit var mainBinding: ActivityMainBinding | ||
|
||
|
||
private var placeList: List<Place> = emptyList() | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.activity_main) | ||
mainBinding = ActivityMainBinding.inflate(layoutInflater) | ||
setContentView(mainBinding.root) | ||
|
||
if (placeList.isNullOrEmpty()) { | ||
mainBinding.emptyMainText.visibility = View.VISIBLE | ||
} else { | ||
mainBinding.emptyMainText.visibility = View.GONE | ||
} | ||
|
||
setupRecyclerViews(mainBinding) | ||
setupSearchEditText(mainBinding) | ||
observeViewModel(mainBinding) | ||
|
||
mainBinding.xmark.setOnClickListener { | ||
mainBinding.search.setText("") | ||
} | ||
} | ||
|
||
private fun setupRecyclerViews(mainBinding: ActivityMainBinding) { | ||
mainBinding.placeResult.apply { | ||
layoutManager = LinearLayoutManager(this@MainActivity, LinearLayoutManager.VERTICAL, false) | ||
adapter = placeAdapter | ||
} | ||
|
||
mainBinding.searchHistory.apply { | ||
layoutManager = LinearLayoutManager(this@MainActivity, LinearLayoutManager.HORIZONTAL, false) | ||
adapter = historyAdapter | ||
} | ||
} | ||
|
||
private fun setupSearchEditText(mainBinding: ActivityMainBinding) { | ||
val searchEditText = mainBinding.search | ||
|
||
searchEditText.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) {} | ||
|
||
override fun afterTextChanged(s: Editable?) { | ||
val searchText = searchEditText.text.toString() | ||
viewModel.getSearchResult(searchText) | ||
} | ||
}) | ||
} | ||
|
||
private fun observeViewModel(mainBinding: ActivityMainBinding) { | ||
viewModel.searchHistoryList.observe(this@MainActivity, Observer { | ||
historyAdapter.setData(it) | ||
}) | ||
viewModel.getSearchHistoryList() | ||
|
||
viewModel.placeList.observe(this@MainActivity, Observer { | ||
placeAdapter.setData(it) | ||
mainBinding.emptyMainText.visibility = if (it.isNullOrEmpty()) View.VISIBLE else View.GONE | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.content.Context | ||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.MutableLiveData | ||
import androidx.lifecycle.ViewModel | ||
|
||
class MainViewModel(context: Context) : ViewModel() { | ||
private val dbHelper: DBHelper = DBHelper(context) | ||
private val db = dbHelper.writableDatabase | ||
private val preferenceManager = MapApplication.prefs | ||
|
||
private var _placeList = MutableLiveData<List<Place>>() | ||
private val _searchHistoryList = MutableLiveData<List<SearchHistory>>() | ||
|
||
init { | ||
_searchHistoryList.value = getSearchHistory() | ||
} | ||
|
||
val searchHistoryList: LiveData<List<SearchHistory>> | ||
get() = _searchHistoryList | ||
|
||
val placeList: LiveData<List<Place>> | ||
get() = _placeList | ||
|
||
fun insertPlace(place: Place) { | ||
dbHelper.insert(db, place) | ||
} | ||
|
||
override fun onCleared() { | ||
super.onCleared() | ||
if (db.isOpen) db.close() | ||
} | ||
|
||
fun getSearchResult(searchText: String) { | ||
if (searchText.isEmpty()) { | ||
_placeList.postValue(emptyList()) | ||
} else { | ||
val rDb = dbHelper.readableDatabase | ||
val places = mutableListOf<Place>() | ||
val query = "SELECT * FROM ${PlaceContract.TABLE_NAME} WHERE ${PlaceContract.TABLE_COLUMN_NAME} LIKE ?" | ||
val cursor = rDb.rawQuery(query, arrayOf("%$searchText%")) | ||
|
||
if (cursor != null) { | ||
if (cursor.moveToFirst()) { | ||
do { | ||
val name = cursor.getString(cursor.getColumnIndexOrThrow(PlaceContract.TABLE_COLUMN_NAME)) | ||
val address = cursor.getString(cursor.getColumnIndexOrThrow(PlaceContract.TABLE_COLUMN_ADDRESS)) | ||
val category = cursor.getString(cursor.getColumnIndexOrThrow(PlaceContract.TABLE_COLUMN_CATEGORY)) | ||
val place = Place(name, address, category) | ||
places.add(place) | ||
} while (cursor.moveToNext()) | ||
} | ||
cursor.close() | ||
} | ||
_placeList.postValue(places) | ||
} | ||
} | ||
|
||
fun getSearchHistoryList() { | ||
_searchHistoryList.value = getSearchHistory() | ||
} | ||
|
||
private fun getSearchHistory(): ArrayList<SearchHistory> { | ||
return preferenceManager.getArrayList(Constants.SEARCH_HISTORY_KEY) | ||
} | ||
|
||
fun saveSearchHistory(searchHistory: SearchHistory) { | ||
val currentList = getSearchHistory() | ||
preferenceManager.savePreference(Constants.SEARCH_HISTORY_KEY, searchHistory, currentList) | ||
getSearchHistoryList() | ||
} | ||
|
||
fun deleteSearchHistory(position: Int) { | ||
preferenceManager.deleteArrayListItem(Constants.SEARCH_HISTORY_KEY, position) | ||
getSearchHistoryList() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.app.Application | ||
import android.content.SharedPreferences | ||
|
||
class MapApplication: Application() { | ||
companion object { | ||
lateinit var prefs: PreferenceManager | ||
} | ||
|
||
override fun onCreate() { | ||
prefs = PreferenceManager(applicationContext) | ||
super.onCreate() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package campus.tech.kakao.map | ||
|
||
data class Place ( | ||
val name: String, | ||
val address: String, | ||
val category: String, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.util.Log | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.widget.AdapterView | ||
import android.widget.BaseAdapter | ||
import android.widget.TextView | ||
import androidx.appcompat.content.res.AppCompatResources | ||
import androidx.recyclerview.widget.RecyclerView | ||
|
||
class PlaceAdapter(var items: List<Place>, val inflater: LayoutInflater, var itemClickListener: OnItemClickListener): RecyclerView.Adapter<PlaceAdapter.PlaceViewHolder>() { | ||
|
||
interface OnItemClickListener { | ||
fun onItemClick(position: Int) {} | ||
} | ||
|
||
override fun onCreateViewHolder( | ||
parent: ViewGroup, | ||
viewType: Int | ||
): PlaceAdapter.PlaceViewHolder { | ||
val view = inflater.inflate(R.layout.place_item, parent, false) | ||
return PlaceViewHolder(view) | ||
} | ||
|
||
override fun onBindViewHolder(holder: PlaceAdapter.PlaceViewHolder, position: Int) { | ||
holder.name.text = items[position].name | ||
holder.address.text = items[position].address | ||
holder.category.text = items[position].category | ||
} | ||
|
||
override fun getItemCount(): Int { | ||
return items.size | ||
} | ||
|
||
fun setData(searchResults: List<Place>) { | ||
items = searchResults | ||
notifyDataSetChanged() | ||
} | ||
|
||
fun getItem(position: Int): Place { | ||
return items[position] | ||
} | ||
|
||
inner class PlaceViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { | ||
val name: TextView | ||
val address: TextView | ||
val category: TextView | ||
|
||
init { | ||
name = itemView.findViewById<TextView>(R.id.place) | ||
address = itemView.findViewById<TextView>(R.id.address) | ||
category = itemView.findViewById<TextView>(R.id.category) | ||
|
||
itemView.setOnClickListener { | ||
itemClickListener.onItemClick(absoluteAdapterPosition) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.