개발
카카오 API 이미지 검색 삽질 기록
kks950115
2024. 1. 30. 21:44
728x90
api로 이미지 검색 결과를 받는데 자꾸 결과에 널이 뜬다....
이상하다. 뭐가 문제지? 했는데 interface에 반환타입 KakaoImg가 문제였다.
KakaoImg클래스와 APIResponse 클래스는 구조는 같다.
다만 KakaoImg 가 APIResponse 를 한번 더 감싼 형태라서 정보를 담아내지 못헀던 것이다.
반환타입을 APIResponse으로 바꾸니 바로 되었다.
아래는 그 당시 코드.
interface
interface KakaoImageAPI {
@GET("v2/search/image")
suspend fun getPost(
@Header("Authorization") apiKey : String,
@Query("query") searchKeyword: String
) : KakaoImg
}
constants.kt
object Constants {
const val KAKAO_AUTHKEY = "KakaoAK 개인용 키"
}
data class Post(
@SerializedName("thumbnail_url")
val img : String,
@SerializedName("display_sitename")
val title : String,
@SerializedName("datetime")
val time : String
)
data class MetaData(
@SerializedName("total_count")
val totalCount: Int,
@SerializedName("pageable_count")
val pageableCount : Int,
@SerializedName("is_end")
val isEnd:Boolean
)
data class APIResponse(
@SerializedName("meta")
val metaData : MetaData,
val documents : MutableList<Post>
)
data class KakaoImg (val imgResponse: APIResponse)
networkclient.kt
object NetWorkClient {
private const val BSEE_URL = "https://dapi.kakao.com/"
private fun createOkHttpClient(): OkHttpClient{
val interceptor = HttpLoggingInterceptor()
if(BuildConfig.DEBUG){
interceptor.level = HttpLoggingInterceptor.Level.BODY
} else {
interceptor.level = HttpLoggingInterceptor.Level.NONE
}
return OkHttpClient.Builder()
.connectTimeout(20,TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.addNetworkInterceptor(interceptor)
.build()
}
private val imageRetrofit = Retrofit.Builder()
.baseUrl(BSEE_URL)
.addConverterFactory(GsonConverterFactory.create()).client(
createOkHttpClient()
).build()
val imageNetwork : KakaoImageAPI= imageRetrofit.create(KakaoImageAPI::class.java)
}
searchFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnSearch.setOnClickListener {
val keyword = binding.etSearch.text.toString()
loadImage(keyword)
}
}
private fun loadImage(str:String) {
CoroutineScope(Dispatchers.Main).launch {
val responseData = getPosts(str)
posts = responseData.APIResponse.documents
val imgAdapter = ImageAdapter(posts)
binding.rvImgItem.adapter = imgAdapter
binding.rvImgItem.layoutManager = GridLayoutManager(context,2)
binding.rvImgItem.hasFixedSize()
}
}
private suspend fun getPosts(str:String) = withContext(Dispatchers.IO){
NetWorkClient.imageNetwork.getPost(Constants.KAKAO_AUTHKEY,str)
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
tools:context=".SearchFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#dddddd"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="@+id/et_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:background="@color/white"
android:padding="10dp"
android:text="아이유"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_search"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:text="검색"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_imgItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
rv_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:id="@+id/iv_like"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:elevation="2dp"
android:visibility="invisible"
android:src="@drawable/heart_empty"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_img"
android:layout_width="200dp"
android:layout_height="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:ellipsize="end"
android:maxLines="2"
android:text="이름이름이름이름이이름이름이름이름이름름이름이름이름이름이름이름"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_img" />
<TextView
android:id="@+id/tv_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="날짜"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
728x90
반응형