거두절미하고, 안됩니다.
하지만 아무것도 모르는 나는 ViewHolder에 Retrofit을 넣을 수밖에 없었던 피치못할 사정이 있었는데....
사용자가 검색한 가수와 비슷한 느낌의 가수를 추천해주는 API를 쓰고 있었다. 근데 이 API가 이미지를 제공하지 않아서 카카오 이미지 검색 API를 활용해 어울리는 가수 이미지를 찾으려 했다. 그래서 가수 정보 데이터를 활용하는 ViewHolder 안에 카카오 이미지 검색 API와 통신하는 Retrofit을 넣었다.
그러니까 정리하면,
inner class SearchArtistViewHolder(binding: LayoutMusicListSearchedBinding) : RecyclerView.ViewHolder(binding.root) {
private val image: ImageView = binding.musicListImg
private val name: TextView = binding.musicListTitle
private val genre: TextView = binding.musicListSinger
private val favorite: ImageView = binding.musicListIcon
fun bindArtist(info: SimilarArtist) {
name.text = info.Name
genre.text = info.wTeaser
favorite.setImageResource(R.drawable.icon_favorite)
searchingImg(info.Name)
}
private fun searchingImg(keyword: String) {
...
searchingMusic.enqueue(object: Callback<ArtistImgData> {
override fun onResponse(
call: Call<ArtistImgData>,
response: Response<ArtistImgData>
) {
Log.d("Retrofit", "이미지 찾기 | 현재 키워드 : $keyword")
val body = response.body()
if (body != null) {
Log.d("Retrofit", "이미지 찾기 | 통신 성공")
Glide.with(context).load(body.documents[0].thumbnail_url)
.apply(RequestOptions().placeholder(R.drawable.album_art)).fitCenter()
.into(image)
}
else {
Log.d("Retrofit","이미지 찾기 | 바디 null")
}
}
override fun onFailure(call: Call<ArtistImgData>, t: Throwable) {
Log.d("Retrofit", "이미지 찾기 | 통신 실패", t)
}
})
}
}
일단 의도대로 동작은 하지만.... ViewHolder 내에 Retrofit이 있는 게 영 신경 쓰여서 코드를 뜯어 고쳤다.
private val artistList = ArrayList<SimilarArtist>()
private val artistNameList = ArrayList<String>()
private fun initializeData() {
artistList.clear()
artistNameList.clear()
searchingMusic()
similarArtist()
}
전체 코드는 복잡하니까 가장 하단에 넣겠다. 우선은 중요한 부분부터 뜯어보자!
private fun initializeData() {
artistList.clear()
artistNameList.clear()
searchingMusic()
similarArtist()
}
for (i in 0 until artistList.size) {
Log.d("Retrofit","${i+1} / ${artistList.size} 번째 도는 중")
getArtistImg(artistNameList[i], i)
}
if (body != null) {
Log.d("Retrofit", "이미지 찾기 | 통신 성공")
artistList[time].imgUrl = body.documents[0].thumbnail_url
count++
Log.d("Retrofit", "$count 번째 잘 들어갔나.... ${artistList[time].imgUrl}")
if (count == artistList.size) {
setArtistAdapter(artistList)
}
}
private val artistList = ArrayList<SimilarArtist>()
private val artistNameList = ArrayList<String>()
private fun initializeData() {
artistList.clear()
artistNameList.clear()
searchingMusic()
similarArtist()
}
private fun similarArtist() {
val baseUrl = " https://tastedive.com/api/"
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
val service: SearchingService = retrofit.create(SearchingService::class.java)
val searchingArtist = service.searchSimilarArtist(targetArtist = keyword, info = 1, type = "music", limit = 3)
searchingArtist.enqueue(object : Callback<MusicSimilarData> {
override fun onResponse(call: Call<MusicSimilarData>, response: Response<MusicSimilarData>) {
Log.d("Retrofit", "가수 찾기 | 현재 키워드 : $keyword")
val body = response.body()
if (body != null) {
Log.d("Retrofit", "가수 찾기 | 통신 성공")
for (i in 0 until body.Similar.Info.size) {
artistList.add(body.Similar.Info[i])
artistNameList.add(body.Similar.Info[i].Name)
}
for (i in 0 until body.Similar.Results.size) {
artistList.add(body.Similar.Results[i])
artistNameList.add(body.Similar.Results[i].Name)
}
for (i in 0 until artistList.size) {
Log.d("Retrofit","${i+1} / ${artistList.size} 번째 도는 중")
getArtistImg(artistNameList[i], i)
}
}
else {
Log.d("Retrofit","가수 찾기 | 바디 null")
}
}
override fun onFailure(call: Call<MusicSimilarData>, t: Throwable) {
Log.d("Retrofit", "가수 찾기 | 통신 실패", t)
}
})
}
var count = 0
private fun getArtistImg(keyword: String, time: Int) {
val baseUrl = "https://dapi.kakao.com/v2/search/"
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
val service: SearchingService = retrofit.create(SearchingService::class.java)
val searchingMusic = service.searchArtistImg(auth = BuildConfig.KAKAO_IMAGE_API_AUTH, target = keyword, page = 1, size = 1)
searchingMusic.enqueue(object : Callback<ArtistImgData> {
override fun onResponse(
call: Call<ArtistImgData>,
response: Response<ArtistImgData>
) {
Log.d("Retrofit", "이미지 찾기 | 현재 키워드 : $keyword")
val body = response.body()
if (body != null) {
Log.d("Retrofit", "이미지 찾기 | 통신 성공")
artistList[time].imgUrl = body.documents[0].thumbnail_url
count++
Log.d("Retrofit", "$count 번째 잘 들어갔나.... ${artistList[time].imgUrl}")
if (count == artistList.size) {
setArtistAdapter(artistList)
}
} else {
Log.d("Retrofit", "이미지 찾기 | 바디 null")
}
}
override fun onFailure(call: Call<ArtistImgData>, t: Throwable) {
Log.d("Retrofit", "이미지 찾기 | 통신 실패", t)
}
})
}
물론 지금 코드도 엉망진창이지만.. 적어도 ViewHolder에서는 구출했다~
벨로그 처음 써서 쉽지 않네.... 나중에 정리를 좀 해야겠다.