[Android] DataBinding - Binding Adapter

ErroredPasta·2022년 5월 25일
0

Android-DataBinding

목록 보기
4/4

Binding Adapter

Binding adapter를 이용하여 값을 View에 어떻게 binding할지 지정해줄 수 있습니다. 대표적인 예로 아래와 같이 URL을 이용하여 이미지를 라이브러리를 통해 불러오는 경우가 많은데 이를 binding adapter를 이용하여 간단하게 할 수 있습니다.

fun ImageView.load(
    uri: String,
    corner: Float = 0f,
    scaleType: Transformation<Bitmap> = CenterInside(),
    @DrawableRes placeholder: Int = R.drawable.ic_baseline_add_a_photo_24
) = Glide.with(this)
    .load(uri)
    .placeholder(placeholder)
    .transition(DrawableTransitionOptions.withCrossFade(factory)) // fade-in 애니메이션
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .apply {
        // 이미지의 라운딩 처리
        if (corner > 0f) {
            transform(scaleType, RoundedCorners(corner.fromDpToPx()))
        }
    }.into(this)

URL string과 DataBinding을 이용하여 이미지를 불러오기 위해서 알맞은 binding adapter를 지정해주어야 합니다.
Binding adapter는 Java의 경우 static method로 정의를 하고 Kotlin의 경우 top-level function이나 object의 method로 정의가 가능합니다. 단, binding adapter는 static해야 하므로 Kotlin으로 정의할 때 object의 method로 정의할 경우 @JvmStatic annotation을 적용하여야 합니다.

@BindingAdapter("imageUrl")
fun setImageByUrl(imageView: ImageView, imageUrl: String?) {
    if (imageUri == null) return

    imageView.load(imageUrl)
}

위와 같이 @BindingAdapter annotation으로 binding adapter를 지정해주어야 합니다. Annotation의 값으로 View에서 사용될 속성의 이름을 지정해주어야 합니다. Parameter는 아래와 같습니다.

  • 첫번째 parameter : Binding adapter를 적용할 View입니다. 해당 예제에서는 URL의 이미지를 ImageView에 적용하는 것이므로 ImageView로 지정하였습니다.
  • 두번쨰 parameter : imageUrl 속성으로 받을 값입니다. 예제에서는 이미지 URL을 String으로 받습니다.

Binding adapter를 지정해주었으면 layout xml에서 해당 속성을 사용할 수 있게 됩니다.

<ImageView
    android:id="@+id/updateMarketDetailImage"
    imageUrl="@{updateMarketUiState.marketDetailImage}"
 	... />

여러 속성 값을 받을 경우

여러개의 값을 View에 적용하여야 하는 경우도 존재합니다. 위의 이미지 URL 예제에서 만약 rounding 처리를 하고 싶을 경우 불러올 이미지의 URL 값과 얼마나 이미지 rounding을 처리할지에 대한 값을 받아야 합니다.
이럴 경우 @BindingAdapter에 이미지 URL 속성 이름과 rounding 값을 받을 속성 이름을 지정해주면 됩니다.

@BindingAdapter(value = ["imageUrl", "cornerRadius"], requireAll = false)
fun setImageByUrl(imageView: ImageView, imageUri: String?, corner: Float) {
    if (imageUri == null) return

    imageView.load(imageUri, corner)
}

여러 속성을 지정해주면 여러 속성의 값을 받아야하고 그에 대한 parameter들을 지정해주어야 합니다.

  • 첫번째 parameter : Binding adapter를 적용할 View입니다.
  • 두번째 parameter : @BindingAdapter에 첫번째로 정의한 속성으로 받을 값입니다. 해당 예제에서는 imageUrl의 속성으로 String값을 받습니다.
  • 세번째 parameter : 첫번째로 정의한 속성으로 받을 값입니다. cornerRadius의 속성으로 Float값을 받습니다.

이미지 rounding의 경우 optional하기 때문에 requireAll을 false로 지정하였습니다.

requireAll은 binding adapter가 호출되려면 모든 속성이 필요한지 지정합니다. true일 경우 value로 지정한 속성 값이 모두 할당되어야 호출이 됩니다. false일 경우에는 어느 하나의 속성이라도 할당이 될 경우 adapter가 호출됩니다. requireAll은 기본 값으로 true를 갖습니다.

Reference

[1] "Binding adapters," Android Developers, last modified Oct 27, 2021, accessed May 25, 2022, https://developer.android.com/topic/libraries/data-binding/binding-adapters.

profile
Hola, Mundo

0개의 댓글