데이터 바인딩과 뷰 바인딩은 모두 직접 뷰를 참조하는데 사용할 수 있는 결합 클래스를 자동 생성해 준다. 이 두 바인딩의 차이점을 무엇일까?
즉 간단한 화면, 동적인 데이터가 없는 화면은 viewBinding을 이용하는 것이 효율적이고,
동적 UI 콘텐츠가 많거나 바인딩에 관한 소스를 최적화 하고 싶을 때, 역할을 분리하고 싶을 때 dataBinding을 사용하는 것이 효율적이다.
ViewModel에서의 초기 값을 Null값으로 초기화하고, DataBinding을 사용하여 UI와 엮는 과정에 생긴 문제
네트워크에서 데이터를 불러오기 전까지는 Null로 해당 데이터가 유지 되기 때문에 이를 해결할 필요가 있었다.
@JvmStatic
@BindingAdapter("setTextNullable")
fun bindSetTextNullable(view: TextView, text: String?) {
text?.let {
view.text = it
}
}
// In XML
app:setTextNullable="@{String.valueOf(viewmodel.myCloverInfo.lastOneMonthFeedCount)}" />
BindingAdapter를 사용, Custom Setter를 생성하여 null체크를 진행 했다.
Array가 존재할 때
1. Array가 null인지 체크필요
2. Array가 null이 아니면 isEmpty로 빈 배열인지 체크
해야 할 때
// In Xml
<import type="org.apache.commons.lang3.ArrayUtils" />
app:gone="@{!(ArrayUtils.isEmpty(viewmodel.myCloverInfo.cloverCounts.toArray()))}">
Array의 null 및 Empty를 체크해주는 Java Utils 라이브러리를 사용하여 null체크를 진행하였다.
Data binding does not need to check for null value, it will be handled by binding class.
더 쉬운 방법이 있었는데, 데이터 바인딩은 기본적으로 NullPointerException을 지원한다. 예를 들어 항목 자체가 null인 경우에도 일반적으로 이를 확인하고 기본값(null 등)을 할당한다고 한다.
즉 BindingAdapter를 따로 구현할 필요 없이 그냥 null값을 넣어도 된다는 것
다음과 같이 null이 아닐 때 default값을 집어 넣을 수 있다.
android:text='@{item.title != null ? user.title : ""}'
or
android:text="@{item.title == null ? `` : item.title"
또는 Null 병합 연산자, Null Coalescing Operator (??) 를 사용할 수도 있다.
(??) 는 item이 null이 아니면 왼쪽, null이면 오른쪽을 선택한다.
android:text='@{item.title ?? ""}'
그렇다면 kotlin에서의 확장함수를 사용하면 어떨까?
kotlin에서의 kotlin extention함수를 xml에서 사용하고 싶다면 어떻게 해야될까??
결론은 불가능하다.
안드로이드의 databinding은 XML 코드로 부터 Java코드를 생성하기 때문에 Java에서 지원하지 않는 함수는 사용이 불가능하다.
@kotlin.internal.InlineOnly
public inline fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
return this == null || this.length == 0
}
kotlin 확장함수는 kotlin.internal.InlineOnly로 정의되어 있어 kotlin코드에서만 사용이 가능하다.
구글에서 Kotlin을 밀고 있는 만큼 XML에서 Java 코드말고 Kotlin코드를 생성한다고 하면 사용이 가능할지도 모르겠다.
https://stackoverflow.com/questions/36227194/data-binding-set-property-if-it-isnt-null