DataBinding은 ViewModel객체와 함께 사용된 LiveData와 잘 동작한다. 현재 ViewModel을 데이터 바인딩 하고 있으니 이제 LiveData를 포함 시킬 준비가 되었다.
이번 태스크에서는 GuessTheWord 앱을 LiveData를 데이터 바인딩에 사용하여 data의 변경을 UI에 알려주는 작업을 해 볼 것이다. 이렇게 되면 LiveData를 observer 메소드를 통해 감시할 필요가 없게 된다.
Step 1: Add word LiveData to the game_fragment.xml file
이번 단계에서는 현재단어를 나타내는 TextView와 ViewModel의 LiveData를 바인딩 시켜 볼 것이다.
1. game_fragment.xml에서 word_text id를 가지는 TextView에 android:text를 추가해준다. android:text에 LiveData를 추가해주면 된다. 저번 태스크에서 GameViewModel을 바인딩 시켰으므로 gameViewModel의 word를 셋팅 해 준다.
- ViewModel을 layout에 바인딩
<layout ...>
<data>
<variable
name="gameViewModel"
type="com.example.android.guesstheword.screens.game.GameViewModel" />
</data>
<androidx.constraintlayout...
- 바인딩된 ViewModel의 LiveData를 셋팅
<TextView
android:id="@+id/word_text"
...
android:text="@{gameViewModel.word}"
... />
layout에 정의한 데이터를 보면 word.value를 사용하지 않는다. 대신 진짜 LiveData 객체를 사용할 수 있다. 이 LiveData객체는 word 변수의 현재 값를 나타낸다. 만약 word의 값이 null이라면, LiveData 객체는 빈 스트링값을 나타낼 것이다.
2. GameFragment의 onCreateView()안에서 gameViewModel이 초기화 된 후에 현재 액티비티를 binding객체의 lifecycle owner로 지정 해 준다. 이것은 LiveData의 범위를 정의하여 LiveData가 game_fragment.xml 안에서 view들을 자동으로 업데이트 할 수 있게 해준다.
binding.gameViewModel = ...
// Specify the current activity as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = this
3. GameFragment에서 Livedata word의 observer를 지운다. 아래의 코드를 지우면 된다.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
4. 앱을 실행 시키고 게임을 플레이 해 본다. 현재 단어가 업데이트 되는 것은 UI Controller(GameFragment)안의 observer없이 업데이트 되는 것이다. 이것은 위에서 LiveData를 view에 직접 바인딩 했기 때문에 가능한 것이다!
Step 2: Add score LiveData to the score_fragment.xml file
이번 단계에서는 score관련 LiveData를 score fragment안의 score TextView에 바인딩 해 볼 것이다.
1. score_fragment.xml안에서 score text view에 android:text 속성을 추가한다. 그리고 scoreViewModel.score을 text속성에 셋팅 해 준다. score는 int값이기 때문에 String.valueOf()를 이용해서 변환 해 준다.
<TextView
android:id="@+id/score_text"
...
android:text="@{String.valueOf(scoreViewModel.score)}"
... />
2. ScoreFragment안에서 scoreViewModel이 초기화 된 후에 현재 fragment를 binding객체의 lifecycle owner로 지정 해 준다.
binding.scoreViewModel = ...
// Specify the current activity as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = this
3. ScoreFragment안의 score객체를 감시하고 있던 observer를 제거 해 준다.
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
4. 앱을 실행하고, 게임을 플레이 해 본다. 이제 observer를 LiveData객체에 따로 붙히지 않아도 view에 직접 바인딩 되기 때문에 게임이 잘 진행 된다.
Step 3: Add string formatting with data binding
layout안에서 데이터 바인딩과 함께 문자열 형식을 추가할 수 있다. 이번 태스크에서 현재 단어를 "현재단어"로 감싸는 작업을 해 볼 것이다. 하단의 Current Score : 7 과 같이 현재 점수를 나타내는 접두사를 추가 할 수 있다.
1. string.xml안에서 아래의 string value를 추가 해 준다. 해당 문자열은 word와 score를 포맷팅 하는데 사용될 것 이다. %s와 %d는 현재단어 (%s-문자열) 와 현재점수 (%d - 숫자)가 들어갈 자리를 표시하는 것 이다.
<string name="quote_format">\"%s\"</string>
<string name="score_format">Current Score: %d</string>
2. game_fragment.xml안에서 word_text의 text속성을 quote_format을 통해 업데이트 해 준다.
<TextView
android:id="@+id/word_text"
...
android:text="@{@string/quote_format(gameViewModel.word)}"
... />
3. score_text도 word_text와 유사하게 업데이트 하면 된다. 이때에는 score_format을 이용해서 업데이트 하면 된다.
<TextView
android:id="@+id/score_text"
...
android:text="@{@string/score_format(gameViewModel.score)}"
... />
4. game_fragment.xml의 score_text에 LiveData를 바인딩 했으니 GameFragment에서 score_text에 등록한 observer를 제거 해 준다.
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
5. 프로젝트를 clean, rebuild하고 앱을 실행한다. 그리고 게임을 플레이 해 본다. 현재 단어와 점수들이 아래와 같이 포맷팅 되어 나타나게 된다.
'study' 카테고리의 다른 글
[안드로이드 기능 분석 #1] NavigationDrawer (0) | 2019.12.20 |
---|---|
안드로이드 DataBinding, MVVM 구구단 (0) | 2019.12.12 |
Android Kotlin Fundamentals 05.3 #1 Data binding with ViewModel and LiveData - Add ViewModel data binding (0) | 2019.12.08 |
Android Kotlin Fundamentals 05.2 #8 :Summary (0) | 2019.12.08 |
파이썬 #1) VSCODE에서 에서 파이썬 개발하기 (0) | 2019.12.06 |