Skip to content
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

Merged
merged 6 commits into from
Jul 12, 2024

Conversation

sumintnals
Copy link

@sumintnals sumintnals commented Jul 10, 2024

3주차 과제

🛠️기능 사항(2단계)

카카오로컬 API를 사용한다.

  • 장소를 검색하는 기능
  • 검색어를 입력하면 검색 결과 목록 표시 기능
  • 검색 결과 목록 세로 스크롤 기능
  • 입력한 검색어는 X를 눌러서 삭제할 수 있다.
  • 검색 결과 목록에서 하나의 항목을 선택할 수 있다.
  • 선택된 항목은 검색어 저장 목록의 앞부분에 추가된다.
  • 저장된 검색어 목록은 가로 스크롤이 된다.
  • 저장된 검색어는 X를 눌러서 삭제할 수 있다.
  • 저장된 검색어는 앱을 재실행하여도 유지된다.

가능한 MVVM 아키텍처 패턴을 적용하도록 한다.


⚠️참고사항

과제 제출 일정에 맞추느라 0단계 PR을 올리고 바로 step1에서 1단계 작업을 했습니다. 죄송합니다!!

0단계 PR

어려운점

검색 결과가 페이지 단위로 나오는 것 같던데, 어떤 식으로 해야 나머지 페이지의 결과를 다 보여줄 수 있을지 고민이 됩니다...

‼️피드백 받고 싶은 부분, 궁금한 부분

  • 아직 2주차때 구현한 DB 부분과 로직들을 살려뒀는데, 3주차 과제서부터는 사용을 안하니까 지워도 되는 것인지 궁금합니다!
  • 라이브 클론코딩 강의에서, retrofit 객체의 선언을 뷰모델에서 해야 하는지 or 뷰모델에서 해야 하는지에 관한 질문이 나왔었는데, 멘토님이 스스로 생각해보라고 하셨습니다. 다른 블로그를 찾아보았는데

RetrofitInstance 객체를 매번 생성하면 비용이 너무 높기 때문에 object 키워드를 사용해 싱글톤으로 한 번만 생성한 후 필요시 RetrofitInstance를 호출하여 retrofitService 객체에 접근합니다. 출처

라고 설명되어 있었는데, retrofit을 이렇게 싱글톤으로 접근하는 것과 뷰모델에 선언하는 것 중 어느 것이 더 나은 것인지 궁금합니다!

  • 검색어를 입력할 때 마다 요청을 하는 것이 뷰가 빠르게 바뀌어 정신없기도 하고, 너무 많은 요청을 보낼 것 같다는 생각이 들어서(카카오맵에서도 글자 입력이 멈추고 약간 시간이 지난 후 검색 결과가 나오는 것을 보았습니다!)
    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 = s.toString().trim()

                handler.removeCallbacksAndMessages(null)
                handler.postDelayed({
                    viewModel.getPlace(searchText)
                }, delayMillis)
            }
        })
    }

이런 식으로 했는데(타이머 기능을 구현하고 싶었는데 어떻게 해야할 지 몰라 지피티의 도움을 받았습니다...) 이렇게 했을 때에 문제점이 있을까요??

📷앱 사진



sumintnals and others added 5 commits July 9, 2024 02:14
변경 사항
Place.kt: json 데이터를 받아올 Location 데이터 클래스를 만들었습니다.
MainViewModel: getPlace()를 통해 위치를 받아옵니다.
RetrofitInstance: 레트로핏 객체를 싱글톤으로 받아옵니다.
RetrofitService: 데이터를 받아오기 위한 RetrofitService입니다
PlaceAdapter: 받아오는 리스트를 locationList로 바꾸고, 제일 하위 카테고리를 가져오는 getLastCategory 함수를 정의했습니다.
"
@sumintnals sumintnals changed the title 전남대 Android_장수민_2주차 과제(1단계) 전남대 Android_장수민_3주차 과제(1단계) Jul 10, 2024
Copy link

@omjoonkim omjoonkim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1단계 과제 하시느라 고생하셨습니다.

질문해주신 내용은 코멘트로 남겼습니다.
PR은 머지할테니, 코멘트에 대한 반영은 다음 PR에서 이어서 진행해주세요~

@@ -54,6 +55,8 @@ class MainActivity : AppCompatActivity() {

private var placeList: List<Place> = emptyList()

private var locationList: List<Document> = emptyList()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

locationList, placeList이 MainActivity에서 선언되어야 할 필요가 있을까요? 불필요한 필드 선언은 코드를 복잡하게 만듭니다. :)
만약 불필요하다면 코드를 지워주세요~!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵!! 처음에 추가해 둔 placeList 보고 같이 선언해 둔 건데 그럴 필요가 없었던 것 같습니다! 2단계 진행하면서 지우도록 하겠습니다!

val searchText = s.toString().trim()

handler.removeCallbacksAndMessages(null)
handler.postDelayed({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

만약 불필요한 네트워크 콜을 줄이고, 버퍼를 주고싶은 것이라면 postDelayed대신 텍스트 변경 이벤트가 throttleing되도록 만들어 보세요. 코루틴을 활용하여 적용해보시면 좋을 것 같네요 :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵...!! 알려주셔서 감사합니다!

if (query.isEmpty()) {
_locationList.value = emptyList()
} else {
retrofitService.getPlaces("KakaoAK "+BuildConfig.KAKAO_REST_API_KEY, query).enqueue(object : Callback<Location> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뷰모델이 직접 retrofitService에 접근하는 대신, 이러한 데이터 조작 역할을 repository 컴포넌트를 만들어 위임해보세요. 이전에 전달드렸던 안드로이드 공식 문서의 아키텍쳐 부분을 참고하여 수정해주세요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵! 수정하겠습니다!

import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
val retrofitService = Retrofit.Builder()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

만약 여러 쓰레드에서 동시에 retrofitService에 접근하게 된다면 어떻게 될까요? 이에 대해서 생각해보시고 적절한 해결방법을 코드에 적용해보세요. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아... 생각을 못 하고 있었습니다!! 적절한 방법을 찾아보겠습니다!

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추후 DI 개념을 학습하게 되신다면, 어디에 선언해야 하는지에 대한 고민에 답을 얻으실 수 있으실거에요. 현재로서는 뷰모델에 선언보다는 object로 선언하는 것이 더 좋아보입니다 :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네! 코드리뷰 해주셔서 감사합니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 제가 컨플릭을 고쳤는데... 괜찮은 걸까요!?!! 제가 하면 안되는 것은 아니였겠죠...??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아니요! 컨플릭트 해결해주셔야 제가 머지가 가능해서요. ㅎㅎ PR은 머지하도록 하겠습니다.

@omjoonkim omjoonkim merged commit 8d78c7e into kakao-tech-campus-2nd-step2:sumintnals Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants