[Android Kotlin 기초] 8-2. Loading and displaying images from the Internet

Android Kotlin Fundamentals: Loading and displaying images from the Internet

안드로이드에서 인터넷에서 이미지 로드는 글라이드 라이브러리를 많이 사용합니다.

##글라이드란? 이미지를 다운로드, 버퍼링, 디코딩 및 캐시 를 수월하고 쉽게 할 수 있는 라이브러리
Glide를 사용하지 않으면 위 작업 시 매우 많은 일들을 수행해야한다.

implementation "com.github.bumptech.glide:glide:$version_glide"

Glide에는 기본적으로 두 가지가 필요

1) 사용할 이미지의 URL 2) ImageView 등등 이미지를 표시할 뷰

Glide.with(imgView.context).load(imgUri).into(imgView)
  1. Uri이미지를 가져 오는 서버에 보안 체계가 필요하기 때문에 최종 개체가 HTTPS 체계를 사용하기를 원한다면, HTTPS 체계를 사용하려면 빌더에 buildUpon.scheme(“https”) 추가
    val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
    
  2. 인터넷에서 이미지 불러오기전에 placeholder 함수로 불러오기전 임시 이미지를 설정할 수 있음 , 이미지 불러오는데 에러가 표시됬다면 혹은 error 로 에러가 났을 때 표시할 이미지를 설정할 수 있음
    @BindingAdapter("imageUrl")
    fun bindImage(imgView: ImageView, imgUrl: String?) {
    imgUrl?.let {
        val imgUri = 
           imgUrl.toUri().buildUpon().scheme("https").build()
        Glide.with(imgView.context)
                .load(imgUri)
                .apply(RequestOptions()
                        .placeholder(R.drawable.loading_animation)
                        .error(R.drawable.ic_broken_image))
                .into(imgView)
    }
    }
    
  3. 데이터 바인딩 과 라이브데이타를 사용한다면 바인딩어댑터를 이용해서 사용하는편입니다.(2번 예제) 아래에서 viewModel.property는 LiveData의 value가 바로 연동이 됩니다. 불필요한 옵저버 코드를 감소시킬 수 있습니다.
    app:imageUrl="@{viewModel.property.imgSrcUrl}"
    

위 내용을 바탕으로 그외 구글 예제에서 리사이클러뷰를 이용해서 데이터를 받아 이미지 로드하는 예제가 나와있음

  1. 리싸이클러뷰 이미지 불러오기 오류처리
    enum class MarsApiStatus { LOADING, ERROR, DONE }
    

    예제에서 사용하는 방식은 enum class 를 추가

private val _status = MutableLiveData<MarsApiStatus>()

val status: LiveData<MarsApiStatus>
   get() = _status

라이브 데이터에 위에 만든 enum 모델로 타입을 지정해서 만듭니다.

_status.value = MarsApiStatus.LOADING
try {
   _properties.value = MarsApi.retrofitService.getProperties()
   _status.value = MarsApiStatus.DONE
} catch (e: Exception) {
   _status.value = MarsApiStatus.ERROR
}

위 예제는 코틀린을 사용한 레트로핏에서 통신 반환값을 라이브데이타에 넣어주는 순간. 위에 만들어 놓은 _status를 상황마다 값을 할당 해줍니다.

@BindingAdapter("marsApiStatus")
fun bindStatus(statusImageView: ImageView, 
          status: MarsApiStatus?) {
  when (status) {
        MarsApiStatus.LOADING -> {
            statusImageView.visibility = View.VISIBLE
            statusImageView.setImageResource(R.drawable.loading_animation)
           }
         MarsApiStatus.ERROR -> {
              statusImageView.visibility = View.VISIBLE
              statusImageView.setImageResource(R.drawable.ic_connection_error)
           }
         MarsApiStatus.DONE -> {
              statusImageView.visibility = View.GONE
            }
   }
}

위 처럼 이넘 클래스로 만든 모델을 기준으로 상수값 분기처리를 해줍니다.

<ImageView
   android:id="@+id/status_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:marsApiStatus="@{viewModel.status}" />

현재 이미지 불러오기 상태값을 표시할 이미지뷰에 해당 바인딩 어댑터를 할당합니다.

-그러면 인터넷에서 값을 가져오는 상황에 따라 불러오는 중인지, 불러오기 실패했는지 상황에 맞게 이미지가 변하거나 숨겨집니다.