Android 앱개발을하면서 DataBinding에 익숙해졌다면 BindingAdapter라는것을 알게될것입니다.
DataBinding을 사용하면 xml에 해당코드를 등록하여 사용할수있게 해주는 JetPack라이브러리중 하나입니다.
이런 DataBinding을 사용할경우 기존에 xml에 View속성을 추가하려면 해당 View에 지원하는 속성들만 지원이 가능했고 만약 추가하려고 한다면 커스텀뷰를 만들어 해당 View에 대한 속성을 추가해야만 했습니다. 그렇지만 위에서도 말했듯 DataBinding은 xml에서 코드로 접근할수 있기에 BindingAdapter로 함수를만들면 xml에서 BindingAdapter에 지정하여 속성들을 사용하여 해당함수를 호출할수 있게됩니다. 이방식으로 지정한 속성들은 커스텀 뷰처럼 프로퍼티로 지정하지 않았기 때문에 코드에서 해당속성의 값에 접근하는것은 불가하고 해당함수로 접근해야합니다.
BindingAdapter라는것이 View에 속성을 추가하고 xml에서 해당값을 DataBinding으로 가져온 값이나 속성등을 넣어 더 다양한 기능을 할수있다는것을 알게되었습니다.
공식문서에서는 어떻게 설명하고 있을까요?

BindingAdapter는 표현식과 값이 뷰로 설정되는 방식을 조작하는 데 사용되는 메서드에 적용됩니다. 가장 간단한 예는 뷰와 설정할 값이 있는 public static 메서드를 가지는 것입니다:
@BindingAdapter("android:bufferType") public static void setBufferType(TextView view, TextView.BufferType bufferType) { view.setText(view.getText(), bufferType); }위의 예제에서는 TextView에 android:bufferType이 사용될 때 setBufferType 메서드가 호출됩니다.
이전에 설정된 값을 사용하는 것도 가능합니다. 이전 값이 먼저 나열되어야 합니다
@BindingAdapter("android:onLayoutChange") public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue, View.OnLayoutChangeListener newValue) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (oldValue != null) { view.removeOnLayoutChangeListener(oldValue); } if (newValue != null) { view.addOnLayoutChangeListener(newValue); } } }바인딩 어댑터가 여러 속성을 사용할 수 있는 경우, 해당 바인딩 어댑터와 관련된 모든 속성에 바인딩 표현식이 있을 때에만 호출됩니다. 속성 간에 불규칙한 상호 작용이 있는 경우 유용합니다. 예를 들어:
@BindingAdapter({"android:onClick", "android:clickable"}) public static void setOnClick(View view, View.OnClickListener clickListener, boolean clickable) { view.setOnClickListener(clickListener); view.setClickable(clickable); }매개변수의 순서는 BindingAdapter에서 값들의 순서와 일치해야 합니다.
바인딩 어댑터는 선택적으로 DataBindingComponent를 확장하는 클래스를 첫 번째 매개변수로 사용할 수도 있습니다. 이렇게 하면 바인딩 중에 값이 전달될 때, 직접 inflate 메서드에서 또는 DataBindingUtil.getDefaultComponent()에서 값을 간접적으로 사용할 때 전달됩니다.
바인딩 어댑터가 인스턴스 메서드인 경우, 생성된 DataBindingComponent에는 메서드를 호출하는 데 사용할 바인딩 어댑터 클래스의 인스턴스를 가져올 수 있는 getter가 있습니다.
적용시 이런식으로 적용가능 하며
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.example.MyViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onLayoutChange="@{viewModel.layoutChangeListener}">
<!-- 여기에 다른 뷰들을 추가할 수 있습니다 -->
</LinearLayout>
</layout>
이두함수는 동일한 동작을 합니다.
@BindingAdapter(value = "code_text")
fun ImageView.setPin(codeText: CharSequence?, index: Int) {
if (codeText != null) {
setImageResource(R.drawable.ic_baseline_circle_black)
}else {
setImageResource(R.drawable.ic_baseline_circle_gray)
}
}
@BindingAdapter(value = "code_text")
fun setPin(view:ImageView, codeText: CharSequence?, index: Int) {
with(view){
if (codeText != null) {
setImageResource(R.drawable.ic_baseline_circle_black)
}else {
setImageResource(R.drawable.ic_baseline_circle_gray)
}
}
}
reference
https://developer.android.com/topic/libraries/data-binding/binding-adapters?hl=ko
https://todaycode.tistory.com/53