[Android / Kotlin] Firebase Storage 연결해서 DataBinding된 RecyclerView에 이미지 적용하기

선주·2022년 4월 5일
1

Android

목록 보기
11/11
post-thumbnail

🔨 build.gradle 의존성 추가

Project 단위 build.gradle 파일을 열어 아래 라인을 추가해주자.

dependencies {
    classpath 'com.google.gms:google-services:4.3.10'
}

Module단위 build.gradle 파일을 열어 아래 라인을 추가해주자.

plugins {
    id 'com.google.gms.google-services'
}
dependencies {
    // Firebase
    implementation 'com.google.firebase:firebase-core:20.1.2'
    implementation 'com.google.firebase:firebase-storage:20.0.1'

    // Gilde
    implementation 'com.github.bumptech.glide:glide:4.12.0'
} 

Firebase Storage에 저장된 이미지를 불러와서 RecyclerView에 뿌려줄 것이므로 Firebase에 접근하기 위한 dependency와 이미지 로딩 프레임워크인 Glide의 dependency를 추가해준 것이다.


📂 item_info.xml

이미지를 넣어줄 ImageView에 app:imageUrl="@{info.thumbnail}"을 추가해준다.

DataBinding을 위한 모든 세팅은 완료되어 있는 상태라고 가정한다.
서버에서 데이터를 가져오면서 InfoDTO가 갱신되고, 이 InfoDTO의 thumbnail(=이미지 파일명) 정보가 BindingAdapter에 전달될 것이다.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
  
    <data>
        <variable
            name="info"
            type="com.momoand.momo.retrofit.domains.InfoDTO" />
    </data>
  
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="20dp">
      
        <androidx.cardview.widget.CardView
            android:id="@+id/item_info_cardview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardCornerRadius="10dp"
            app:cardElevation="0dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
          
            <ImageView
                android:id="@+id/item_info_thumbnail"
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#eeeeee"
                app:imageUrl="@{info.thumbnail}" />

        </androidx.cardview.widget.CardView>

        <TextView
            android:id="@+id/item_info_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:letterSpacing="-0.05"
            android:text="@{info.title}"
            android:textColor="@color/black"
            android:textSize="16dp"
            app:layout_constraintTop_toBottomOf="@id/item_info_cardview" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

📂 BindingAdapter.kt

BindingAdapter로 app:imageUrl 속성을 정의한다. 여기서 Firebase에 연결하고 이미지를 가져와서 Glide를 통해 ImageView에 세팅해줄 것이다.

BindingAdapter는 InfoDTO의 thumbnail(이미지 파일명) 정보를 url이라는 파라미터로 받는다.

참고로, @BindingAdapter 어노테이션을 사용한 함수의 경우 static으로 접근이 가능해야 하기 때문에 static 함수로 설정해주기 위한 어노테이션인 @JvmStatic을 추가해준다. 이를 추가해주지 않으면 에러가 발생한다.

object BindingAdapter {
    @JvmStatic
    @BindingAdapter("app:imageUrl")
    fun loadImage(imageView: ImageView, url: String){
    
        val storage: FirebaseStorage = FirebaseStorage.getInstance("gs://~")
        val storageReference = storage.reference
        val pathReference = storageReference.child("images/$url")

        pathReference.downloadUrl.addOnSuccessListener { uri ->
            Glide.with(imageView.context)
                .load(uri)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .centerCrop()
                .into(imageView)
        }
    }
} 

스토리지 인스턴스를 생성할 때, getInstance에 파라미터로 들어가는 "gs://~"는 아래 사진처럼 파이어베이스 콘솔에서 Storage로 들어가면 나오는 gs://~를 그대로 넣어주면 된다.

스토리지의 폴더 안에 있는 이미지를 가져와야 한다면 인스턴스에 추가로 참조를 만들어서 child"폴더명/파일명"을 넣어준다.

해당 경로에서 파일을 받아오는 것에 성공했다면 이제 Glide로 ImageView에 이미지를 세팅해줄 차례!

  • with() : View, Fragment 혹은 Activity로부터 Context를 가져온다.
  • load() : 이미지를 로드한다. 다양한 방법으로 이미지를 불러올 수 있다. (Bitmap, Drawable, String, Uri, File, ResourId(Int), ByteArray)
  • diskCacheStrategy() : 디스크에 캐싱하지 않으려면 DiskCacheStrategy.NONE로 준다. 다음과 같은 옵션이 있다. (ALL, AUTOMATIC, DATA, NONE, RESOURCE)
  • centerCrop() : 이미지의 scaleType을 centerCrop으로 지정한 것이다.
  • into() : 이미지를 보여줄 View를 지정한다.


끄읏~!


참고
Medium | platfarm tech team
Blog | Dev Blog by Yena

profile
기록하는 개발자 👀

0개의 댓글