본문 바로가기

Android

[Android] DataBinding 사용하기

반응형

데이터 바인딩은 UI를 구성함에 있어 코드상에 반복적인 귀찮은 작업을 해소시켜주는 기능으로 보면 된다.

선언부에 기계적으로 작성해야한 했던 findById() 를 적어도 java파일 안에서 그만 볼수 있으니까 

findViewById<TextView>(R.id.sample_text).apply {
        text = viewModel.userName
    }

 

 

 

이런 코드를 layuot을 구성하는 xml파일 안에서 java파일에서 지정해준 해당 위젯의 변수명과 매치시켜주면 된다.

<TextView
        android:text="@{viewmodel.userName}" />
    

 

이점은 ? 

파일의 단순화, 유지보수의 편리성, 메모리누수 및 nullpoint excention을 방지할수 있다. 

 

1. 빌드환경 - 데이터 바인딩 추가

android {
        ...
        dataBinding {
            enabled = true
        }
    }

dataBinding요소를 build.gradle 에 위와같이 추가해준다. 

데이터 결합 라이브러리는 유연성과 광범위한 호환성을 모두 제공하는 지원 라이브러리이며 Android 4.0(API 수준 14) 이상을 실행하는 기기에서 사용할 수 있고, 최신 Gradle용 Android 플러그인을 프로젝트에 사용하는 것이 좋다. 그러나 데이터 결합은 버전 1.5.0 이상에서 지원됨. 

2. 레이아웃 및 바인딩 수식 

<layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable name="user" type="com.example.User"/>
       </data>
</layout>

예를 들어, 위와 같다고 한다면 data태그내의 user라는 변수는 com.example.User의 파일안에서 사용할 수있다. 

데이터 결합 - 각 레이아웃 파일의 결합 클래스가 생성됨 (기본적으로 생성 클래스 이름은 레이아웃 파일이름 기반으로 파스칼 표기법으로 변환, 접미사(Binding이 추가됨) 

  activity_main.xml 레이아웃의 생성되는 클래스는 ActivityMain+Binding = ActivityMainBinding 이 됨

Fragment, ListView 또는 RecyclerView 어댑터 내에서 데이터 결합 항목을 사용하고 있다면 다음 코드 예에서와 같이 결합 클래스 또는 DataBindingUtil 클래스의 inflate() 메서드를 사용할 수도 있다 

   val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
    // or
   val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

 

표현식 언어 

산술 + - / * %
문자열 연결 +
논리 && ||
바이너리 & | ^
단항 + - ! ~
전환 >> >>> <<
비교 == > < >= <=(<는 &lt;으로 이스케이프 처리해야 함)
instanceof
그룹화 ()
리터럴 - 문자, 문자열, 숫자, null
변환
메서드 호출
필드 액세스
배열 액세스 []
삼항 연산자 ?:

Null병합 연산자 - null 병합 연산자(??)는 왼쪽 피연산자가 null이 아니면 왼쪽 피연산자를 선택하고 null이면 오른쪽 피연산자를 선택

android:text="@{user.displayName ?? user.lastName}"

//기능적으로 동일 
android:text="@{user.displayName != null ? user.displayName : user.lastName}"

* 생성된 데이터 결합 코드는 자동으로 null 값을 확인하고 null 포인터 예외를 방지

. 예를 들어 @{user.name} 표현식에서 user가 null이면 user.name null이 기본값으로 할당. age의 유형이 int user.age를 참조하면 데이터 결합은 0의 기본값을 사용.

속성 참조 - 표현식은 다음 형식을 사용하여 클래스의 속성을 참조

android:text="@{user.lastName}"

 

표현식은 다음 구문을 사용하여 ID로 레이아웃의 다른 뷰를 참조할 수 있다 

<EditText
        android:id="@+id/example_text"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"/>
    <TextView
        android:id="@+id/example_output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{exampleText.text}"/> // TextView 뷰는 동일한 레이아웃의 EditText 뷰를 참조

 

리소스 참조  

표현식은 앱 리소스를 참조할 수 있다. 

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

매개변수를 제공하여 형식 문자열과 복수형을 평가 할수도 있고 

android:text="@{@string/nameFormat(firstName, lastName)}"
    android:text="@{@plurals/banana(bananaCount)}"

속성 참조  뷰 참조를 리소스 매개변수로 전달할 수 있다

android:text="@{@string/example_resource(user.lastName, exampleText.text)}" 
// EditText(exampleText.text)에 입력된 텍스트가 user.lastName로 전달되는것 ! 

 

이벤트 처리 

데이터 결합을 사용하면 뷰에서 전달되는 표현식 처리 이벤트를 작성할 수 있음. 이벤트 속성 이름은 몇 가지 예외를 제외하고 리스너 메서드의 이름에 따라 결정된다. View.OnClickListener에는 onClick() 메서드가 있으므로 이 이벤트의 속성은 android:onClick.

  • 메서드 참조: 표현식에서 리스너 메서드의 서명과 일치하는 메서드를 참조. 표현식이 메서드 참조로 계산되면 데이터 결합은 리스너에서 메서드 참조 및 소유자 객체를 래핑하고 타겟 뷰에서 이 리스너를 설정. 표현식이 null로 계산되면 데이터 결합은 리스너를 생성하지 않고 대신 null 리스너를 설정.
 class MyHandlers {
        fun onClickFriend(view: View) { ... }
    }
    
    
    ....
  <TextView android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@{user.firstName}"
             android:onClick="@{handlers::onClickFriend}"/>
   ...

   

  • 리스너 결합: 이벤트가 발생할 때 계산되는 람다 표현식 데이터 결합은 항상 리스너를 생성하여 뷰에서 설정합니다. 이벤트가 전달되면 리스너는 람다 표현식을 계산
class Presenter {
        fun onSaveClick(task: Task){}
    }

...

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
            <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="@{() -> presenter.onSaveClick(task)}" />
        </LinearLayout>
...        
        

 

메서드 참조와 리스너 결합의 주요 차이점은 실제 리스너 구현이 이벤트가 트리거될 때가 아니라 데이터가 결합될 때 생성된다는 점. 이벤트가 발생할 때 표현식을 계산하려면 리스너 결합을 사용

 

레이아웃 및 결합 표현식  |  Android 개발자  |  Android Developers

표현식 언어를 사용하면 뷰에 의해 전달된 이벤트를 처리하는 표현식을 작성할 수 있습니다. 데이터 결합 라이브러리는 레이아웃의 뷰를 데이터 객체와 결합하는 데 필요한 클래스를 자동으로

developer.android.com

 

 

샘플소스

github.com/android/databinding-samples

 

android/databinding-samples

Contribute to android/databinding-samples development by creating an account on GitHub.

github.com

 

참조 

developer.android.com/topic/libraries/data-binding/expressions?hl=ko

반응형