데이터 바인딩은 ViewModel 객체와 같이 사용되는 LiveData와 잘 작동한다.
저번 코드랩에서 ViewModel 객체에 데이터 바인딩을 추가했으므로 LiveData를 적용할 준비가 됐다.
Add word LiveData to the game_fragment.xml file
이번에는 word 텍스트뷰를 ViewModel안에 있는 LiveData와 직접 바인드한다.
1. xml의 word_text에 text 속성을 추가해준다.
바인딩 변수를 사용해 GameViewModel의 word LiveData 객체로 설정한다.
<TextView
android:id="@+id/word_text"
...
android:text="@{gameViewModel.word}"
... />
여기서 우리는 word.value를 사용할 필요가 없다. 대신, 실제 LiveData 객체를 사용할 수 있다.
만약 word 값이 null이면 빈 문자열을 보여줄 것이다.
2. GameFragment의 onCreateView에서 gameViewModel을 초기화한 후,
Fragment view를 바인딩 변수의 lifecycle owner로 설정한다.
이는 LiveData 객체의 범위를 정의하여 레이아웃 안의 뷰를 자동으로 업데이트하도록 해준다.
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
3. GameFragment에서 LiveData의 word에서 옵저버를 제거한다.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(viewLifecycleOwner, Observer { newWord ->
binding.wordText.text = newWord
})
4. 이제 앱을 실행하면 현재 단어는 observer method가 없이도 업데이트되고 있다.
Add score LiveData to the score_fragment.xml file
이번에는 score 텍스트뷰를 LiveData의 score와 바인드한다.
1. score_fragment.xml에서 score 텍스트뷰에 text 속성을 추가하고, scoreViewModel.score를 할당한다.
score는 int형이기 때문에 String.valueOf 메소드를 사용해주어야 한다.
<TextView
android:id="@+id/score_text"
...
android:text="@{String.valueOf(scoreViewModel.score)}"
... />
2. ScoreFragment에서 scoreViewModel 초기화 후, 현재 액티비티를 바인딩 변수의 lifecycle owner로 설정한다.(?)
(액티비티는 코드랩 측의 오타인 듯 하다. 코드 예제에서는 아래 보다시피 fragment view라고 명시해두었다.)
binding.scoreViewModel = ...
// 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
3. ScoreFragment에서 score 객체의 옵저버를 제거한다.
// Add observer for score
viewModel.score.observe(viewLifecycleOwner, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
4. 이제 앱을 실행하면 현재 점수는 observer method가 없이도 업데이트되고 있다.
Add string formatting with data binding
레이아웃에서 우리는 데이터 바인딩과 string formatting을 추가할 수 있다.
이번에는 현재 word 주위에 따옴표를 추가해 형식을 지정한다.
또한, score 앞에 Current Score 라는 접두사를 추가한다.
1. strings.xml에 아래의 string을 추가한다. word와 score 텍스트뷰에서 사용할 것이고, %s와 %d는 placeholder이다.
<string name="quote_format">\"%s\"</string>
<string name="score_format">Current Score: %d</string>
2. xml에서 word_text의 text 속성을 위에서 추가한 quote_format string resource를 사용하도록 바꿔준다.
그리고 gameViewModel.word를 넘겨줌으로써 현재 word를 문자열 서식의 인자로 전달해준다.
<TextView
android:id="@+id/word_text"
...
android:text="@{@string/quote_format(gameViewModel.word)}"
... />
3. score 텍스트도 word처럼 비슷하게 바꿔준다.
xml에서 score_text 텍스트뷰에 text 속성을 추가한다.
score_format string resource를 사용하고 이는 한 숫자 인수를 %d라는 placeholder를 통해 보여줄 것이다.
gameViewModel.score를 바로 위에서 word에 적용했던 것처럼 전달해준다.
<TextView
android:id="@+id/score_text"
...
android:text="@{@string/score_format(gameViewModel.score)}"
... />
4. GameFragment 클래스의 onCreateView에서 score에 대한 옵저버 코드를 삭제한다.
viewModel.score.observe(viewLifecycleOwner, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
5. 이제 앱을 실행하면 점수와 단어가 서식화되어 있다.
'Android' 카테고리의 다른 글
Codelab으로 LiveData transform해보기 - 1. Add a Timer (0) | 2023.05.19 |
---|---|
Codelab으로 DataBinding 알아보기 - 4. 정리(完) (1) | 2023.05.17 |
Codelab으로 DataBinding 알아보기 - 2. Add ViewModel data binding (0) | 2023.05.11 |
Codelab으로 DataBinding 알아보기 - 1. 과정 소개 (0) | 2023.05.09 |
안드로이드 FCM 백그라운드 푸시 알림 받기 (4) | 2023.05.08 |