ViewModel은 Activity에서는 Activity가 완전히 종료될 때까지, 그리고 Fragment에서는 Fragment가 분리될 때까지 메모리에 남아있도록 설계되어 있다!
class WriteViewModel : ViewModel() {
//...
private var _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
val writeTitle = MutableLiveData<String>()
//...
}
org.sopt.daangnmarket_android.ui.viewmodel.WriteViewModel
이라는 WriteViewModel
클래스 타입의 viewmodel
이라는 변수를 사용하는 것이 데이터바인딩의 핵심이다.
WriteViewModel
은 클래스이기 때문에, viewmodel
이라는 변수에 WriteViewModel
클래스로 생성한 객체를 할당해주어야 한다.
private val writeViewModel by activityViewModels<WriteViewModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding =
DataBindingUtil.inflate(layoutInflater, R.layout.fragment_write, container, false)
binding.viewmodel = writeViewModel
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}
binding
객체의 viewmodel
이라는 변수는 WriteFragment
의 writeViewModel
이라는 객체로 할당해주는 과정, 즉 xml 코드 상에서 태그 안에 선언한 viewmodel
이라는 변수에 writeViewModel
이라는 객체를 할당해준 과정이다.
이걸 안해서 실행이 안됐었다....^_ㅠ
- lifecycleOwner는 Activity에서와 Fragment에서 할당하는 값이 다르다!
// Activity에서는 Activity 자기 자신을 lifecycleOwner로 지정
binding.lifecycleOwner = this
// Fragment에서는 viewLifecycleOwner를 lifecycleOwner로 지정
binding.lifecycleOwner = viewLifecycleOwner
자 이제 xml을 자세히 봐줄까
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="co.kr.myapplication.presentation.viewmodel.SignInViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
레이아웃으로 감싸고,
Activity의 binding.viewmodel = writeViewModel
에서 viewmodel
이
xml에서 name="viewmodel"
과 같은 칭구칭긔다.
이제 TextView를 보면
//xml
android:textColor="@{viewmodel.writePrice.length == 0 ? @color/gray_c4c4c4 : @color/black}"
//양방향 아님
android:text="@={viewmodel.writePrice}"
//양방향
이렇게 단방향 양방향 구분이 가넝ㅋㅋ
private var _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
val writeTitle = MutableLiveData<String>()
LiveData는 abstract class이기 때문에 LiveData Class를 상속받은 MutableLiveData
를 사용한다.
MutableLiveData
: 값의 get/set 모두를 할 수 있음LiveData
: 값의 get()만을 할 수 있음Observer Pattern
: 관찰하고 있다가, 상태가 변하면 어떠한 콜백을 수행하는 구조인데 이를 잘 활용하면 매번 값이 변할 때마다 UI, 그러니까 화면을 업데이트하는 코드를 매번 작성하는 번거로움을 줄일 수 있다. LiveData
는 이런 옵저버 패턴을 사용하기 쉽게 만들어둔 것!