데이터 바인딩에서 바인딩 어댑터 사용은 반복적인 코드를 줄이고
프로그래매틱한 영역과 뷰 영역 간의 작업을 좀 더 뚜렷하게 나눌 수 있는, 관심사 분리 법칙에 좀 더 다가갈 수 있는 좋은 방법이다.
데이터 바인딩을 사용 한다면 바인딩 어댑터를 다음과 같이 선언할 수 있다.
@BindingAdapter("isGone")
fun bindIsGone(view: View, isGone: Boolean) {
view.visibility = if (isGone) {
View.VISIBLE
} else {
View.GONE
}
}
@BindingAdapter("imageFromUrl")
fun bindImageFromUrl(view: ImageView, imageUrl: String?) {
if (!imageUrl.isNullOrEmpty()) {
Glide.with(view.context)
.load(imageUrl)
.transition(DrawableTransitionOptions.withCrossFade())
.into(view)
}
}
isGone 은 상태(Boolean)에 따라 뷰를 보여줬다가 사라졌다가 하게 하는 메소드고,
imageFromUrl 은 이미지 url을 받아서 글라이드로 보여주는 메소드다.
이 바인딩 어댑터로 "isGone" 과 "imageFromUrl" 이라는 xml 에서 사용할 수 있는 두가지 "속성"을 선언한 것이다.
xml 레이아웃에서 이 속성을 사용해보자.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.MyFragment">
<data>
<variable
name="Loaded"
type="boolean" />
<variable
name="viewModel"
type="com.unitewikiapp.unitewiki.viewmodels.InfoViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:isGone="@{!Loaded}">
<ImageView
android:layout_width="70dp"
android:layout_height="70dp"
app:imageFromUrl="@{viewModel.infodata.skill1}"/>
</FrameLayout>
</layout>
위의 간단한 예시가 보일 것이다.
isGone 으로 데이터가 전부 로딩이 되어야만 뷰를 보여주도록, 그리고 imageFromUrl로 데이터만 집어넣으면 Glide로 이미지를 보여주도록 하였다.
isGone 의 Loaded 변수는 프래그먼트 내에서 라이브데이터 혹은 플로우를 옵저빙하여 데이터 로딩 상태에 따라 Loaded 변수를 False 혹은 True 로 지정해 줄 것이다.
프래그먼트내에서 Visiblity에 관한 코드를 복잡하게 전부 작성할 필요 없이 직관적으로 Loaded 변수만 지정하면되는 것이다.
그리고 iamgeFromUrl 로 글라이드로 이미지를 표현하도록 하였으므로 저 Glide 에 관한 코드를 프래그먼트에서 이미지마다 일일이 각각 전부 작성할 필요없이, viewModel만 지정해주면 바인딩 어댑터로 인해 Glide로 이미지를 보여준다.
반복적인 코드를 줄인 것을 확인할 수 있다.