<이전글>
<코드랩 과정5 : databinding with livedata and viewmodel>
# 시작하며
이번시간은 데이터바인딩을 통해서 xml에서 데이터를 활용하는 방법을 배웠다. 크게 복잡하지 않기 때문에 간단히 사용 할 수 있다. 근데 난 데이터바인딩으로 xml에서 코드 작성하는게 더 불편한거 같다..
완성본은 아래와 같으며, 기능상의 차이는 없다. 직접 치는 코드가 간결해질 뿐이다.
# 데이터바인딩 사용하는 이유
지금껏 작성했던 코드들을 살펴보면 UI 컨트롤러가 유저 이벤트를 처리하도록 코드를 작성하고, 이에따른 비지니스 로직과 데이터들을 뷰모델에 작성했다. 이러한 뷰들은 xml을통해서 정의했다.
우리가 UI컨트롤러(액티비티나 프래그먼트)에 레이아웃을 binding시켜서 사용했다는 것을 알 수 있다. 버튼처리에대한 로직은 뷰모델이 직접 처리해주지만 중간에 UI컨트롤러가 매개체 역할을 하고 있었다. 즉 직접적으로 연결 돼 있지 않다.
그러나 데이터바인딩을 통해 뷰모델을 결속시키면 위와 같은 과정을 생략 할 수 있다는 것을 알 수 있다.
# 데이터바인딩을 통해 viewModel 결합하기
<layout ...>
<data>
<variable
name="gameViewModel"
type="com.example.android.guesstheword.screens.game.GameViewModel" />
</data>
<androidx.constraintlayout...
xml에 data태그에 변수를 등록한다.
이후 프래그먼트에 viewmodel을 연결시켜준다.
// Set the viewmodel for databinding - this allows the bound layout access
// to all the data in the ViewModel
binding.gameViewModel = viewModel
이렇게 되면 xml에서 onClick,onZoomIn,onZoomOut과 같은 이벤트 리스너를 따로 코드를 작성하지 않고 xml내에서 바로 처리가 가능하다. 마치 리액트를 사용하면서 태그안에 onClick메서드를 넣는거와 같다.
아래와 같이 이벤트 처리 클릭을 달아준다.
<Button
android:id="@+id/skip_button"
...
android:onClick="@{() -> gameViewModel.onSkip()}"
... />
skip, correct, endgame에 대해서도 동일하게 적용시킨다. score도 똑같이 해준다.
그렇게 한다면 아래와 같은 UI컨트롤러에서 작성한 이벤트처리를 생략할 수 있기에, 코드를 지워주도록 한다.
// 삭제 가능!
binding.correctButton.setOnClickListener { onCorrect() }
binding.skipButton.setOnClickListener { onSkip() }
binding.endGameButton.setOnClickListener { onEndGame() }
/** Methods for buttons presses **/
private fun onSkip() {
viewModel.onSkip()
}
private fun onCorrect() {
viewModel.onCorrect()
}
private fun onEndGame() {
gameFinished()
}
# 데이터바인딩을 통해 LiveData 결합하기
LiveData로 손쉽게 결합 할 수 있다. 이를 통해서, 우리가 Observer를 통해서 상태변화가 온다면 UI를 새로 그려주게 했던거와 같은 로직을 지워 줄 수 있다.
예를 들어, 새로운 word를 동작 시켜야하는 과정에서 skip, correct 버튼을 누르면 다음 단어가 나오고 그 단어가 메인화면에 반영됐었다. 이것을 livedata를 통해서 observer를 통해서 관찰했는데 이 것을 생략할 수 잇다.
<TextView
android:id="@+id/word_text"
...
android:text="@{gameViewModel.word}"
... />
binding.gameViewModel = ...
// Specify the fragment view as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = viewLifecycleOwner
아래 코드를 지워주도록 하자
/** Setting up LiveData observation relationship **/
viewModel.word.observe(viewLifecycleOwner, Observer { newWord ->
binding.wordText.text = newWord
})
# 마치며
데이터 바인딩은 MVP , MVVM과 같은 패턴을 사용하기 위해서 유용하게 쓰인다고 한다. xml만 보고도 어느 기능을 하는지 알 수 있다는 장점도 있고 여러 장점이 존재한다.
그러나 클래스가 비대해지고 관리해야하는 파일이 많아진다는 단점도 있다고 한다.