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를 추가해준 것이다.
이미지를 넣어줄 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로 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를 지정한다.
끄읏~!