[Android/Kotlin] Binding Adapter 와 DataBinding

Falco·2022년 9월 5일
0

Android

목록 보기
24/55
post-custom-banner

Binding Adapter(결합 어댑터)에 대해

Binding Adapter, 즉 결합 어댑터는 적절한 프레임워크를 호출하여 XML에 사용자가 지정하는 값을 설정하는 작업을 담당한다.

사전정의된 예로는 android:text 와 같이 속성 값을 설정하는 것 또는 android:onclick 처럼 메서드를 지정하는 것과 같이 이벤트 리스너를 설정하는 작업이 있다.

<TextView
    android:id="@+id/text_email"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{viewModel.userEmailLD}"
  />

사용자 정의 로직 설정

사용자가 원하는 작업을 XML에서 지정하고 싶을 때가 있다. 이럴때는 @BindingAdpater 어노테이션을 사용하여
이처럼 BindingAdpater 어노테이션을 선언하고 이름을 넣어주게 되면 해당 이름으로 선언된 함수를 bind 하여 사용할 수 있게 된다.

다음은 클릭시 Navigator의 popBaskStack을 실행하는 예제이다.

  @JvmStatic
  @BindingAdapter("onBackPressed")
  fun bindOnBackPressed(view: View, onBackPress: Boolean) {
    if (onBackPress) {
      view.setOnClickListener {
        view.findNavController().popBackStack()
      }
    }
  }
  
  // In XML
  <ImageView
  	android:id="@+id/leftarrow_iv"
  	...
  	app:onBackPressed="@{true}" />

매개변수 중 첫 번째 매개변수는 속성과 연결된 뷰의 유형을 결정한다.
두 번째 매개변수는 지정된 속성의 Binding Adapter에서 허용되는 유형을 결정한다.

개발자가 정의하는 Binding Adapter는 충돌이 발생하면 Android 프레임워크에서 제공하는 기본 어댑터보다 우선 적용된다.

	// 기존에 프래그먼트마다 이렇게 달아줘야 했다.
    binding.leftarrowIv.setOnClickListener {
      findNavController().popBackStack()
    }

두개이상의 속성을 받는 어댑터도 설정 가능하다.

    @BindingAdapter("imageUrl", "error")
    fun loadImage(view: ImageView, url: String, error: Drawable) {
        Picasso.get().load(url).error(error).into(view)
    }
    
    <ImageView app:imageUrl="@{venue.imageUrl}" app:error="@{@drawable/venueError}" />

imageUrl이 문자열이 error가 Drawable이면 해당 어댑터가 호출된다.

속성 중 하나라도 설정될 때 설정하려면 requireAll 플래그를 사용한다.

    @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);
        }
    }

requireAll의 값을 조정하여 모든 변수가 필요할지 정할 수 있다.

  • JvmStatic?
    전역 변수의 Getter Setter를 정적 함수로 설정하는 어노테이션이다.

맞춤 변환

특정 유형간에 밪춤 변환을 제공한다.

예를들어 android:background 속성에 Drawable이 필요하지만 지정된 color 값이 Int형(Id값)으로 제공되는 상황일 때,

@BindingConversion 어노테이션을 활용하여 color Id 값을 ColorDrawable로 변활 할 수 있다.

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

그러나 다음과 같이 동일한 표현식에 서로 다른 유형은 사용할 수 없다.

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

객체변환, 이전값 사용하기

DataBinding 및 BindingAdapter를 사용하면 기존의 Fragment.kt 내에서 따로 뷰바인딩을 진행하고 UI를 수정하는 코드가 최적화되어 줄어들 것 이다.

참고 자료

https://developer.android.com/topic/libraries/data-binding/binding-adapters?hl=ko

https://heegs.tistory.com/59

https://todaycode.tistory.com/53

https://dev-imaec.tistory.com/41

profile
강단있는 개발자가 되기위하여
post-custom-banner

0개의 댓글