본문 바로가기

android/Jetpack

4-2 단방향 데이터 바인딩, 양방향 데이터 바인딩

*개인적으로 분석한 내용이므로 틀린 내용이 있을 수 있습니다. 틀린 내용을 댓글로 남겨주시면 수정하도록 하겠습니다!

 

[1]. 단방향 데이터 바인딩 vs 양방향 데이터 바인딩
 1. 단방향 데이터 바인딩: 예를들어 ViewModel 내 특정 프로퍼티의 값이 변화함에 따라 연결된 View 가 변한다. (data 변화 -> view 변화)


 2. 양방향 데이터 바인딩: 단방향 데이터바인딩 기능에 더해 사용자의 입력을 받을 수 있는 View(대표적으로 EditText)에 입력이 들어오거나 이미 입력된 값이 변화하면 연결된 프로퍼티의 값을 변화시킬 수 있다.

 

[2]. 양방향 데이터 바인딩 표현식을 사용했을 때의 코드 분석

 

//EditText 에 입력된 값이 변화할 때 마다 해당 리스너의 onChage 메서드가 호출된다.
private androidx.databinding.InverseBindingListener inputEditTextandroidTextAttrChanged = new androidx.databinding.InverseBindingListener() {
	@Override
	public void onChange() {
		//1. EditText 에 입력된 값을 읽어온다.
		java.lang.String callbackArg_0 = androidx.databinding.adapters.TextViewBindingAdapter.getTextString(inputEditText);

		boolean testViewModelUserNameJavaLangObjectNull = false;
		com.test.databinding.MainViewModel testViewModel = mTestViewModel;

		androidx.lifecycle.MutableLiveData<java.lang.String> testViewModelUserName = null;
		java.lang.String testViewModelUserNameGetValue = null;
		boolean testViewModelJavaLangObjectNull = false;

		testViewModelJavaLangObjectNull = (testViewModel) != (null);
		if (testViewModelJavaLangObjectNull) {
			//2. ViewModel class 내에 선언된 userName 이라는 이름의 프로퍼티 객체를 가져온다.
			testViewModelUserName = testViewModel.getUserName();
			testViewModelUserNameJavaLangObjectNull = (testViewModelUserName) != (null);
			
			if (testViewModelUserNameJavaLangObjectNull) {
				/*
					3. EditText 에 입력된 값을 userName 프로퍼티에 넣는다.
					이때 LiveData 의 값이 변화하기 때문에 자동으로 통지가 되어
					해당 LiveData 에 단방향 바인딩으로 연결된 TextView 역시 업데이트 된다.
				*/ 
				testViewModelUserName.setValue(((java.lang.String) (callbackArg_0)));
			}
		}
	}
};

 

 

@Override
protected void executeBindings() {
	long dirtyFlags = 0;
	synchronized(this) {
		dirtyFlags = mDirtyFlags;
		mDirtyFlags = 0;
	}
	
	com.test.databinding.MainViewModel testViewModel = mTestViewModel;
	androidx.lifecycle.MutableLiveData<java.lang.String> testViewModelUserName = null;
	java.lang.String testViewModelUserNameGetValue = null;

	if ((dirtyFlags & 0x7L) != 0) {
		if (testViewModel != null) {
			testViewModelUserName = testViewModel.getUserName();
		}
		updateLiveDataRegistration(0, testViewModelUserName);

		if (testViewModelUserName != null) {
			testViewModelUserNameGetValue = testViewModelUserName.getValue();
		}
	}

	if ((dirtyFlags & 0x7L) != 0) {
		/*
			5. 단방향 데이터 바인딩의 기능인 Data 변경 -> View 변경을 위해 
			EditText 와 TextView 에 문자열을 setText 메서드를 호출해서 넣어준다.
		*/
		androidx.databinding.adapters.TextViewBindingAdapter.setText(this.inputEditText, testViewModelUserNameGetValue);
		androidx.databinding.adapters.TextViewBindingAdapter.setText(this.outputTextView, testViewModelUserNameGetValue);
	}
	
	if ((dirtyFlags & 0x4L) != 0) {
		/*
			4. EditText 의 text 속성에 양방향 데이터 바인딩 표현식을 작성하면
			EditText 에 입력된 값이 변화할 때마다 이를 감지할 TextWatcher callback 객체를 등록한다.
		*/
		androidx.databinding.adapters.TextViewBindingAdapter.setTextWatcher(this.inputEditText, (androidx.databinding.adapters.TextViewBindingAdapter.BeforeTextChanged)null, (androidx.databinding.adapters.TextViewBindingAdapter.OnTextChanged)null, (androidx.databinding.adapters.TextViewBindingAdapter.AfterTextChanged)null, inputEditTextandroidTextAttrChanged);
	}
}

 

[3]. 요약

특정 View 의 속성에 양방향 데이터 바인딩 표현식을 작성하면 
[주석 4.] View 가 변화하는 것을 감지하기 위한 callback 객체를 등록

-> View 변화가 감지됨

-> [주석 3] callback 객체에서 LiveData 에 setValue 호출(View -> Data)

-> LiveData observer 실행

-> [주석 5] executeBindings 메서드에서 View 업데이트(Data -> View) 

 

'android > Jetpack' 카테고리의 다른 글

Room DB 와 RoomTrackingLiveData  (0) 2022.11.03
5-1. Jetpack Navigation의 구성요소  (0) 2022.10.09
4-1 DataBinding  (1) 2022.10.07
3. LiveData  (0) 2022.10.03
2. ViewModel 과 ViewModelFactory  (0) 2022.10.02