Android

데이터 바인딩 (3) : 바인딩 어댑터

까망사과 2022. 11. 3. 13:00

바인딩 어댑터

바인딩 어댑터는 적절한 프레임워크를 호출하여 값을 설정하는 역할을 수행한다.

이를 사용하면 메서드를 호출하여 값을 변경하고, 바인딩 로직을 제공하고, 반환 객체의 타입을 지정할 수 있다.

 

속성 값 설정하기

바인딩 클래스는 바인딩된 데이터가 변경되면 표현식을 사용하여 뷰에서 세터를 호출해야 한다.

데이터 바인딩 라이브러리는 메서드를 자동으로 결정하거나, 메서드를 명시적으로 선언하거나, 메서드를 선택하는 커스텀 로직을 제공할 수 있다.

 

자동으로 메서드 결정하기

데이터 바인딩 라이브러리는 레이아웃 속성의 이름(네임스페이스는 고려하지 않음)에 해당하는 세터 메서드를 자동으로 검색한다.

예를 들어 android:text="@{user.name}"이라는 표현식을 사용한다면 user.getName()이 반환하는 타입을 전달받는 setText()를 검색한다.

지정한 이름의 속성이 존재하지 않더라도 바인딩은 동작한다.

 

메서드 이름 직접 지정하기

BingindMethods 어노테이션을 사용하면 속성을 원하는 이름의 세터와 연결할 수 있다.

어노테이션은 클래스에 사용하며 여러 BindingMethod 어노테이션을 포함할 수 있다.

 

BindingMethod 어노테이션은 다음 인자를 받는다.

  • attribute
    세터를 연결할 속성의 이름
  • method
    세터와 연결될 세터 메서드의 이름
  • type
    attribute로 지정된 속성과 관련된 뷰 클래스

 

예를 들어 다음 예시에서 android:tint 속성은 setTint()가 아니라 setImageTintList()에 연결된다.

@BindingMethods(value = [
    BindingMethod(
        type = android.widget.ImageView::class,
        attribute = "android:tint",
        method = "setImageTintList")
])

 

커스텀 로직 제공하기

BindingAdapter 어노테이션을 사용하면 속성과 관련된 세터 호출 시 실행되는 로직을 지정할 수 있다.

속성에 연결된 세터가 없거나 커스텀 속성을 만들고자 할 때 사용할 수 있다.

 

세터 메서드에 어노테이션을 추가하고 value 파라미터로 세터와 관련된 속성 이름을 전달한다.

@BindingAdapter("android:paddingLeft")
fun setPaddingLeft(view: View, padding: Int) {
    view.setPadding(
        padding,
        view.getPaddingTop(),
        view.getPaddingRight(),
        view.getPaddingBottom()
    )
}

 

여러 속성이 전달되어야 어댑터가 동작하도록 설정할 수도 있다.

다음 예시의 경우 레이아웃의 ImageView에서 imageUrl 속성의 값이 String이고 error 속성의 값이 Drawable이어야 어댑터가 동작한다.

@BindingAdapter("imageUrl", "error")
fun loadImage(view: ImageView, url: String, error: Drawable) {
    Picasso
        .get()
        .load(url)
        .error(error)
        .into(view)
}

 

한 속성만 전달되어도 어댑터가 동작하도록 하려면 requireAllfalse로 설정한다.

@BindingAdapter(value = ["imageUrl", "placeholder"], requireAll = false)
fun setImageUrl(imageView: ImageView, url: String?, placeHolder: Drawable?) {
    if (url == null) {
        imageView.setImageDrawable(placeholder);
    } else {
        MyImageLoader.loadInto(imageView, url, placeholder);
    }
}

 


객체 변환

자동 변환

바인딩 표현식이 Object를 반환하면 속성 값을 설정하는 세터의 파라미터에 맞는 타입으로 변환된다.

파라미터의 타입이 불명확한 경우 표현식에서 타입을 변환해야 한다.

 

직접 변환

특정 타입으로 직접 변환해야 하는 경우가 있다.

예를 들어 android:background 속성에는 Drawable이 필요하지만 정수 값으로 지정되는 color 값을 제공할 수 있다.

표현식에 사용되는 타입은 서로 다르지 않고 일관되어야 한다.

<View
   android:background="@{isError ? @color/red : @color/white}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

 

이 경우 표현식이 정수값을 반환할 때마다 ColorDrawable로 변환해야 한다.

BindingConversion 어노테이션을 변환 메서드에 추가한다.

@BindingConversion
fun convertColorToDrawable(color: Int) = ColorDrawable(color)

'Android' 카테고리의 다른 글

Lifecycle  (0) 2022.11.11
데이터 바인딩 (4) : 양방향 바인딩  (0) 2022.11.05
데이터 바인딩 (2) : 이벤트 처리 / Observable  (0) 2022.11.01
데이터 바인딩 (1) : 기본 사용법  (0) 2022.10.29
컨텐츠 프로바이더  (0) 2022.09.19