-
Two-way Binding 사용법Android 2020. 12. 22. 23:18
개요
데이터 바인딩은 MVVM에서 없어서는 안되는 요소입니다. MVVM에서 뷰와 뷰모델을 느슨하게 결합하는데 데이터 바인딩이 반드시 필요하기 때문입니다. 반드시 뷰모델의 데이터와 결합한다기보다는 앱의 데이터 요소 자체를 UI 요소에 결합시키는 것이 데이터 바인딩인데, 일반적으로는 뷰모델의 데이터가 변경되면 XML의 데이터도 갱신되게 되는 로직을 많이 구성합니다.
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{viewModel.email}" />
일반적으로 뷰모델의 데이터가 변경되면 XML의 데이터가 갱신되는 단방향적인 데이터 바인딩과 반대로 XML의 데이터가 변경되면 뷰모델의 데이터가 갱신되는 데이터 바인딩은 없을까요? EditText에서 값이 입력됨에 따라 뷰모델의 데이터가 알아서 변경되는 로직은 구성하기 어려울까요? 양방향 데이터 결합인 Two-way Binding이 해답이 될 수 있습니다.
Two-way Binding 사용법
Two-way Bidning은 기존의 ="@{}" 대신, ="@={}" 을 사용하면 됩니다. 이러한 선언법은 androidx.databinding.adapters에 다양한 뷰에 대한 BindingAdapter가 선언되있기 때문에 사용 가능합니다. 대표적으로 EditText의 android:text는 다음과 같이 BindingAdapter로 정의되있습니다.
public class TextViewBindingAdapter { @BindingAdapter("android:text") public static void setText(TextView view, CharSequence text) { final CharSequence oldText = view.getText(); if (text == oldText || (text == null && oldText.length() == 0)) { return; } if (text instanceof Spanned) { if (text.equals(oldText)) { return; // No change in the spans, so don't set anything. } } else if (!haveContentsChanged(text, oldText)) { return; // No content changes, so don't set anything. } view.setText(text); } @InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged") public static String getTextString(TextView view) { return view.getText().toString(); }
BindingAdapter와 별개로 InverseBindingAdapter가 추가로 선언되있는데요. 이 속성은 setText가 호출된 후 다음으로 호출되는 함수를 정의하는 속성인데, Two-way Binding을 사용할 때 발생할 수 있는 무한 루프를 방지하기 위한 장치입니다. 공식 사이트에서 이 부분에 대한 간략한 설명을 볼 수 있습니다. 또 사이트에서 기본적으로 제공되는 Two-way Binding 속성을 확인할 수 있습니다. EditText와 CompoundButton에 대한 속성이 특히 유용해보이네요.
Two-way Binding을 사용한 예는 다음과 같습니다.
<EditText android:id="@+id/et_email" android:layout_width="90dp" android:layout_height="wrap_content" android:textSize="20sp" android:text="@={viewModel.email}" />
해당 EditText에 값을 입력하면 XML의 변수로 선언된 ViewModel의 email 필드의 값이 자동으로 갱신되게 됩니다.
마치며
Two-way Binding은 잘 사용하면 뷰모델과 XML의 로직을 훨씬 간단하게 만들어줄 수 있습니다. textWatcher나 다른 함수 선언 필요없이 속성만 지정해주면 되기 때문입니다. 또 다른 Binidng Adapter를 커스텀해서 RxJava와 같이 사용하면 데이터가 입력될 때마다 자동으로 데이터 발행을 시켜줄 수도 있습니다.
'Android' 카테고리의 다른 글
Android 12 - Notification trampoline restrictions (0) 2021.10.25 Android WorkManager 사용법 (0) 2021.05.04 onBackPressed와 finish의 차이 (0) 2020.12.04 Fragment에서 ViewBinding 사용 시 발생할 수 있는 메모리릭 (0) 2020.11.13 변수의 동시성 제어에 관한 이슈 및 해결 (1) 2020.10.27