Databinding과 ViewBinding 그리고 Databinding에서의 Null 처리

Falco·2022년 9월 5일
0

Android

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

DataBinding과 ViewBinding의 차이

데이터 바인딩과 뷰 바인딩은 모두 직접 뷰를 참조하는데 사용할 수 있는 결합 클래스를 자동 생성해 준다. 이 두 바인딩의 차이점을 무엇일까?

viewBinding

  1. annotaion processing이 필요하지 않아 컴파일이 빠르다.
  2. 사용하기 쉽다. 특별한 태그의 XML 파일이 필요하지 않으며, 앱에 빠르게 적용할 수 있다. 모듈에 바인딩 사용 설정하면 자동으로 레이아웃 binidngclass를 생성해 준다.

dataBinding

  1. layout태그를 사용하여 만든 레이아웃을 처리하고, TAG를 삽입으로써 XML 레이아웃 파일에서 직접 동적 UI 콘텐츠를 다룰 수 있다.
  2. 양방향 데이터 결합을 지원한다.

즉 간단한 화면, 동적인 데이터가 없는 화면은 viewBinding을 이용하는 것이 효율적이고,
동적 UI 콘텐츠가 많거나 바인딩에 관한 소스를 최적화 하고 싶을 때, 역할을 분리하고 싶을 때 dataBinding을 사용하는 것이 효율적이다.

DataBinding에서의 Null처리

겪은 문제

ViewModel에서의 초기 값을 Null값으로 초기화하고, DataBinding을 사용하여 UI와 엮는 과정에 생긴 문제
네트워크에서 데이터를 불러오기 전까지는 Null로 해당 데이터가 유지 되기 때문에 이를 해결할 필요가 있었다.

시도한 방법1

  • settext를 넣을 때 Item이 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체크를 진행 했다.

시도한 방법 2

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에서의 확장함수를 사용하면 어떨까?

  • isNullOrEmpty()를 사용하면 되는거 아닌가?
  • null이 아니라 Blank도 isNullOrBlank()로 체크하면 쉬운데?

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/51986008/can-kotlins-isnullorblank-function-be-imported-into-xml-for-use-with-data-bin

https://stackoverflow.com/questions/36227194/data-binding-set-property-if-it-isnt-null

https://developer.android.com/topic/libraries/view-binding

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

0개의 댓글