1) ViewModelProvider는 레거시 코드이므로 by viewModels() 사용하기
https://ddangeun.tistory.com/80
2) _thumbnailUrls는 MutableLiveData(가변 라이브데이터), 언더바가 없는 thumbnailUrlList는 불변 LiveData. (Backing Property) 언더바가 존재하면 읽기/쓰기 가능, 없으면 읽기만 가능.
private val _thumbnailUrls = MutableLiveData<List<String>>()
val thumbnailUrls: LiveData<List<String>> = _thumbnailUrls
3) RetrofitService interface에서 아래 "Authorization"에 Default 값을 설정
@GET("v2/search/image")
suspend fun getSearchImages(
@Header("Authorization") Authorization: String = "KakaoAK d7dad5f8832c904973babb0a21d079ab", // Default
@Query("query") query: String = "검색어",
@Query("sort") sort: String = "accuracy",
@Query("page") page: Int = 1,
@Query("size") size: Int = 80,
): Response<SearchResponse>
-> Repository에서 다시 한번 값을 선언하여 인자를 넘길 필요가 없음. 아래 (제거)를 보시면 해당 매개변수는 필요 없음(이미 default값으로 위에 작성하였기 때문).
[Repository.kt] authorization 제거
import com.example.imagesearch.network.RetrofitClient
class Repository {
suspend fun searchImages(
query: String,
sort: String,
page: Int,
size: Int,
): SearchResponse? {
return try {
val response = RetrofitClient.RetrofitInstance.retrofitService.getSearchImages(
query = "검색어",
sort = "accuracy",
page = 1,
size = 80
)
if (response.isSuccessful) {
response.body()
} else {
null
}
} catch (e: Exception) {
throw e
}
}
}
// authorization 제거
fun searchImages(query: String, sort: String, page: Int, size: Int) {
viewModelScope.launch {
val result = repository.searchImages(query, sort, page, size)
}
}
4) 검색어에 따라 검색을 하려면 아래와 같이 조금 변경되어야 함
[MainActivity.kt]
// 검색어 저장
private fun searchImages() {
val searchQuery = binding.etSearch.text.toString()
viewModel.searchImages( // 여기서 viewModel 함수를 호출하여 검색
query = searchQuery,
sort = "accuracy",
page = 1,
size = 10
)
saveLastSearch(searchQuery) // 검색을 했으니 "이미지 검색" 화면을 보여줌
showFragment(SearchFragment(), R.id.fragment_container_search)
}
5) Fragment에서 binding 객체를 nullable로 만들고 onDestoyView에서 항상 null 시켜주기
private var _binding: FragmentSearchBinding? = null
private val binding: FragmentSearchBinding
get()=_binding!!
// OnCreateView는 View를 생성하는 역할만 함
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentSearchBinding.inflate(inflater, container, false)
return binding.root
}
// 항상 View와 관련된 작업은 아래 함수에서 하기 (onViewCreated)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter = SearchAdapter(object : SearchAdapter.OnItemClickListener {
override fun onItemClick(thumbnailUrl: String, position: Int) {
// 이미지 클릭시 보관함으로 이동
navigateToKeepFragment(thumbnailUrl)
}
})
val recyclerView: RecyclerView = binding.recyclerView
recyclerView.adapter = adapter
recyclerView.layoutManager = GridLayoutManager(requireContext(), 2)
viewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
// 썸네일 이미지 리스트 설정
val thumbnailUrls = arguments?.getStringArrayList(THUMBNAIL_URLS_KEY)
thumbnailUrls?.let {
viewModel.setThumbnailUrls(it)
}
// _thumbnailUrls를 private으로 만들었기 때문에 thumbnailUrls LiveData를 사용하기
viewModel.thumbnailUrls.observe(viewLifecycleOwner, Observer {
adapter.thumbnailUrls
adapter.notifyDataSetChanged()
})
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // null 시켜주기
}
6)
@SerializedName -> Gson 방식
@Json -> Moshi 방식
'앱 개발 > Chapter_Curriculum' 카테고리의 다른 글
내일배움캠프 후기 - 솔직 (0) | 2024.07.20 |
---|---|
[심화 프로젝트] 회고 (0) | 2024.06.01 |
[과제] 피드백 (앱 개발 숙련) (0) | 2024.05.02 |
[숙련 프로젝트] 회고 (0) | 2024.04.30 |
Today I Learned and Studied (0) | 2024.04.17 |