-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
전남대 Android_장수민_3주차 과제(1단계) #48
Changes from 1 commit
44bbc68
b538030
6e780ef
1fabc74
ff6a47d
05d398d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ android { | |
|
||
buildFeatures { | ||
viewBinding = true | ||
buildConfig = true | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.os.Bundle | ||
import android.os.Handler | ||
import android.os.Looper | ||
import android.text.Editable | ||
import android.text.TextWatcher | ||
import android.util.Log | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import androidx.activity.viewModels | ||
|
@@ -18,13 +19,13 @@ class MainActivity : AppCompatActivity() { | |
} | ||
|
||
private val placeAdapter: PlaceAdapter by lazy { | ||
PlaceAdapter(placeList, | ||
PlaceAdapter(locationList, | ||
LayoutInflater.from(this@MainActivity), | ||
object : | ||
PlaceAdapter.OnItemClickListener { | ||
override fun onItemClick(position: Int) { | ||
val item = placeAdapter.getItem(position) | ||
val searchHistory = SearchHistory(item.name) | ||
val searchHistory = SearchHistory(item.placeName) | ||
viewModel.saveSearchHistory(searchHistory) | ||
} | ||
} | ||
|
@@ -54,6 +55,8 @@ class MainActivity : AppCompatActivity() { | |
|
||
private var placeList: List<Place> = emptyList() | ||
|
||
private var locationList: List<Document> = emptyList() | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
mainBinding = ActivityMainBinding.inflate(layoutInflater) | ||
|
@@ -88,15 +91,21 @@ class MainActivity : AppCompatActivity() { | |
|
||
private fun setupSearchEditText(mainBinding: ActivityMainBinding) { | ||
val searchEditText = mainBinding.search | ||
val handler = Handler(Looper.getMainLooper()) | ||
val delayMillis = 800L | ||
|
||
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) | ||
val searchText = s.toString().trim() | ||
|
||
handler.removeCallbacksAndMessages(null) | ||
handler.postDelayed({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약 불필요한 네트워크 콜을 줄이고, 버퍼를 주고싶은 것이라면 postDelayed대신 텍스트 변경 이벤트가 throttleing되도록 만들어 보세요. 코루틴을 활용하여 적용해보시면 좋을 것 같네요 :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵...!! 알려주셔서 감사합니다! |
||
viewModel.getPlace(searchText) | ||
}, delayMillis) | ||
} | ||
}) | ||
} | ||
|
@@ -107,7 +116,7 @@ class MainActivity : AppCompatActivity() { | |
}) | ||
viewModel.getSearchHistoryList() | ||
|
||
viewModel.placeList.observe(this@MainActivity, Observer { | ||
viewModel.locationList.observe(this@MainActivity, Observer { | ||
placeAdapter.setData(it) | ||
mainBinding.emptyMainText.visibility = if (it.isNullOrEmpty()) View.VISIBLE else View.GONE | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,14 @@ | ||
package campus.tech.kakao.map | ||
|
||
import android.content.Context | ||
import android.util.Log | ||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.MutableLiveData | ||
import androidx.lifecycle.ViewModel | ||
import campus.tech.kakao.map.RetrofitInstance.retrofitService | ||
import retrofit2.Call | ||
import retrofit2.Callback | ||
import retrofit2.Response | ||
|
||
class MainViewModel(context: Context) : ViewModel() { | ||
private val dbHelper: DBHelper = DBHelper(context) | ||
|
@@ -12,6 +17,7 @@ class MainViewModel(context: Context) : ViewModel() { | |
|
||
private var _placeList = MutableLiveData<List<Place>>() | ||
private val _searchHistoryList = MutableLiveData<List<SearchHistory>>() | ||
private var _locationList = MutableLiveData<List<Document>>() | ||
|
||
init { | ||
_searchHistoryList.value = getSearchHistory() | ||
|
@@ -23,6 +29,9 @@ class MainViewModel(context: Context) : ViewModel() { | |
val placeList: LiveData<List<Place>> | ||
get() = _placeList | ||
|
||
val locationList: LiveData<List<Document>> | ||
get() = _locationList | ||
|
||
fun insertPlace(place: Place) { | ||
dbHelper.insert(db, place) | ||
} | ||
|
@@ -75,4 +84,33 @@ class MainViewModel(context: Context) : ViewModel() { | |
preferenceManager.deleteArrayListItem(Constants.SEARCH_HISTORY_KEY, position) | ||
getSearchHistoryList() | ||
} | ||
|
||
fun getPlace(query: String) { | ||
if (query.isEmpty()) { | ||
_locationList.value = emptyList() | ||
} else { | ||
retrofitService.getPlaces("KakaoAK "+BuildConfig.KAKAO_REST_API_KEY, query).enqueue(object : Callback<Location> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 뷰모델이 직접 retrofitService에 접근하는 대신, 이러한 데이터 조작 역할을 repository 컴포넌트를 만들어 위임해보세요. 이전에 전달드렸던 안드로이드 공식 문서의 아키텍쳐 부분을 참고하여 수정해주세요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! 수정하겠습니다! |
||
override fun onResponse( | ||
call: Call<Location>, | ||
response: Response<Location> | ||
) { | ||
if (response.isSuccessful) { | ||
val body = response.body() | ||
if (body != null) { | ||
_locationList.postValue(body.documents) | ||
Log.d("성공", ""+ body.documents) | ||
} else { | ||
_locationList.postValue(emptyList()) | ||
} | ||
} else { | ||
Log.d("태그",response.code().toString()) | ||
} | ||
} | ||
|
||
override fun onFailure(call: Call<Location>, t: Throwable) { | ||
Log.d("error", ""+ t) | ||
} | ||
}) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package campus.tech.kakao.map | ||
|
||
import retrofit2.Retrofit | ||
import retrofit2.converter.gson.GsonConverterFactory | ||
|
||
object RetrofitInstance { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 추후 DI 개념을 학습하게 되신다면, 어디에 선언해야 하는지에 대한 고민에 답을 얻으실 수 있으실거에요. 현재로서는 뷰모델에 선언보다는 object로 선언하는 것이 더 좋아보입니다 :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네! 코드리뷰 해주셔서 감사합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 제가 컨플릭을 고쳤는데... 괜찮은 걸까요!?!! 제가 하면 안되는 것은 아니였겠죠...?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아니요! 컨플릭트 해결해주셔야 제가 머지가 가능해서요. ㅎㅎ PR은 머지하도록 하겠습니다. |
||
val retrofitService = Retrofit.Builder() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약 여러 쓰레드에서 동시에 retrofitService에 접근하게 된다면 어떻게 될까요? 이에 대해서 생각해보시고 적절한 해결방법을 코드에 적용해보세요. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아... 생각을 못 하고 있었습니다!! 적절한 방법을 찾아보겠습니다! |
||
.baseUrl("https://dapi.kakao.com/v2/local/search/") | ||
.addConverterFactory(GsonConverterFactory.create()) | ||
.build() | ||
.create(RetrofitService::class.java) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,15 @@ | ||
package campus.tech.kakao.map | ||
|
||
class RetrofitService { | ||
import com.google.gson.internal.GsonBuildConfig | ||
import retrofit2.Call | ||
import retrofit2.http.GET | ||
import retrofit2.http.Header | ||
import retrofit2.http.Query | ||
|
||
interface RetrofitService { | ||
@GET("keyword") | ||
fun getPlaces( | ||
@Header("Authorization") authorization: String = "KakaoAK "+BuildConfig.KAKAO_REST_API_KEY , | ||
@Query("query") query: String | ||
): Call<Location> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
locationList, placeList이 MainActivity에서 선언되어야 할 필요가 있을까요? 불필요한 필드 선언은 코드를 복잡하게 만듭니다. :)
만약 불필요하다면 코드를 지워주세요~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵!! 처음에 추가해 둔 placeList 보고 같이 선언해 둔 건데 그럴 필요가 없었던 것 같습니다! 2단계 진행하면서 지우도록 하겠습니다!