Skip to content

Commit 044e350

Browse files
committed
add data binding
1 parent 3fc4b3d commit 044e350

File tree

8 files changed

+117
-71
lines changed

8 files changed

+117
-71
lines changed

playground/25-guessing-game/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Guessing Game
22

3-
A guessing game to discover how to use a view model.
3+
A guessing game to discover how to use view models, in conjunction with live data and data binding.
44

55
<p align="center">
66
<img src="screenshot.png" style="width:528px;max-width: 100%;">
@@ -16,5 +16,7 @@ A guessing game to discover how to use a view model.
1616
- using live data.
1717
- restricting direct access to a view model's proerties using backing properties.
1818
- adding a game over property.
19+
- implementing data binding.
20+
- using data binding to call methods.
1921

2022
Based on [Head First Android Development: A Brain-Friendly Guide](https://www.amazon.com/Head-First-Android-Development-Brain-Friendly/dp/1449362184) by David Griffiths and Dawn Griffiths (2021).

playground/25-guessing-game/app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ android {
3131
jvmTarget = '1.8'
3232
}
3333
buildFeatures {
34-
viewBinding true
34+
//viewBinding true
35+
dataBinding true
3536
}
3637
}
3738

playground/25-guessing-game/app/src/main/java/com/hfad/guessinggame/GameFragment.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,28 @@ class GameFragment : Fragment() {
2929
val view = binding.root
3030
viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
3131

32-
viewModel.incorrectGuesses.observe(viewLifecycleOwner, Observer { newValue ->
33-
binding.incorrectGuesses.text = "Incorrect guesses: $newValue"
34-
})
35-
viewModel.livesLeft.observe(viewLifecycleOwner, Observer { newValue ->
36-
binding.lives.text = "You have $newValue lives left"
37-
})
38-
viewModel.secretWordDisplay.observe(viewLifecycleOwner, Observer { newValue ->
39-
binding.word.text = newValue
40-
})
32+
// viewModel.incorrectGuesses.observe(viewLifecycleOwner, Observer { newValue ->
33+
// binding.incorrectGuesses.text = "Incorrect guesses: $newValue"
34+
//})
35+
//viewModel.livesLeft.observe(viewLifecycleOwner, Observer { newValue ->
36+
// binding.lives.text = "You have $newValue lives left"
37+
//})
38+
//viewModel.secretWordDisplay.observe(viewLifecycleOwner, Observer { newValue ->
39+
// binding.word.text = newValue
40+
//})
41+
4142
viewModel.gameOver.observe(viewLifecycleOwner, Observer { newValue ->
4243
if (newValue) {
4344
val action = GameFragmentDirections.actionGameFragmentToResultFragment(viewModel.wonLostMessage())
4445
view.findNavController().navigate(action)
4546
}
4647
})
4748

49+
// set the data binding variable
50+
binding.gameViewModel = viewModel
51+
// respond to live data updates
52+
binding.lifecycleOwner = viewLifecycleOwner
53+
4854
binding.guessButton.setOnClickListener {
4955
viewModel.makeGuess(binding.guess.text.toString().uppercase())
5056
binding.guess.text = null

playground/25-guessing-game/app/src/main/java/com/hfad/guessinggame/GameViewModel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,8 @@ class GameViewModel: ViewModel() {
6464
message += " The word was $secretWord"
6565
return message
6666
}
67+
68+
fun finishGame() {
69+
_gameOver.value = true
70+
}
6771
}

playground/25-guessing-game/app/src/main/java/com/hfad/guessinggame/ResultFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class ResultFragment : Fragment() {
3131
val result = ResultFragmentArgs.fromBundle(requireArguments()).result
3232
viewModelFactory = ResultViewModelFactory(result)
3333
viewModel = ViewModelProvider(this, viewModelFactory).get(ResultViewModel::class.java)
34-
binding.wonLost.text = viewModel.result
34+
//binding.wonLost.text = viewModel.result
35+
binding.resultViewModel = viewModel // set the layout's data binding variable
3536

3637
binding.newGameButton.setOnClickListener {
3738
view.findNavController().navigate(R.id.action_resultFragment_to_gameFragment)
Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,66 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<LinearLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android"
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
43
xmlns:tools="http://schemas.android.com/tools"
5-
android:layout_width="match_parent"
6-
android:layout_height="match_parent"
7-
android:orientation="vertical"
8-
android:padding="16dp"
94
tools:context=".GameFragment">
105

11-
<TextView
12-
android:id="@+id/word"
13-
android:layout_width="wrap_content"
14-
android:layout_height="wrap_content"
15-
android:layout_gravity="center"
16-
android:textSize="36sp"
17-
android:letterSpacing="0.1" />
18-
19-
<TextView
20-
android:id="@+id/lives"
21-
android:layout_width="wrap_content"
22-
android:layout_height="wrap_content"
23-
android:textSize="16sp" />
24-
25-
<TextView
26-
android:id="@+id/incorrect_guesses"
27-
android:layout_width="wrap_content"
28-
android:layout_height="wrap_content"
29-
android:textSize="16sp" />
30-
31-
<EditText
32-
android:id="@+id/guess"
33-
android:layout_width="wrap_content"
34-
android:layout_height="wrap_content"
35-
android:textSize="16sp"
36-
android:hint="@string/guess_a_letter"
37-
android:inputType="text"
38-
android:maxLength="1" />
39-
40-
<Button
41-
android:id="@+id/guess_button"
42-
android:layout_width="wrap_content"
43-
android:layout_height="wrap_content"
44-
android:layout_gravity="center"
45-
android:text="@string/guess" />
46-
47-
</LinearLayout>
6+
<data>
7+
<variable
8+
name="gameViewModel"
9+
type="com.hfad.guessinggame.GameViewModel" />
10+
</data>
11+
12+
<LinearLayout
13+
android:layout_width="match_parent"
14+
android:layout_height="match_parent"
15+
android:orientation="vertical"
16+
android:padding="16dp">
17+
18+
<TextView
19+
android:id="@+id/word"
20+
android:layout_width="wrap_content"
21+
android:layout_height="wrap_content"
22+
android:layout_gravity="center"
23+
android:textSize="36sp"
24+
android:letterSpacing="0.1"
25+
android:text="@{gameViewModel.secretWordDisplay}" />
26+
27+
<TextView
28+
android:id="@+id/lives"
29+
android:layout_width="wrap_content"
30+
android:layout_height="wrap_content"
31+
android:textSize="16sp"
32+
android:text="@{@string/lives_left(gameViewModel.livesLeft)}" />
33+
34+
<TextView
35+
android:id="@+id/incorrect_guesses"
36+
android:layout_width="wrap_content"
37+
android:layout_height="wrap_content"
38+
android:textSize="16sp"
39+
android:text="@{@string/incorrect_guesses(gameViewModel.incorrectGuesses)}" />
40+
41+
<EditText
42+
android:id="@+id/guess"
43+
android:layout_width="wrap_content"
44+
android:layout_height="wrap_content"
45+
android:textSize="16sp"
46+
android:hint="@string/guess_a_letter"
47+
android:inputType="text"
48+
android:maxLength="1" />
49+
50+
<Button
51+
android:id="@+id/guess_button"
52+
android:layout_width="wrap_content"
53+
android:layout_height="wrap_content"
54+
android:layout_gravity="center"
55+
android:text="@string/guess" />
56+
57+
<Button
58+
android:id="@+id/finish_game_button"
59+
android:layout_width="wrap_content"
60+
android:layout_height="wrap_content"
61+
android:layout_gravity="center"
62+
android:text="@string/finish_game"
63+
android:onClick="@{() -> gameViewModel.finishGame()}" />
64+
65+
</LinearLayout>
66+
</layout>
Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<LinearLayout
2+
<layout
33
xmlns:android="http://schemas.android.com/apk/res/android"
44
xmlns:tools="http://schemas.android.com/tools"
5-
android:layout_width="match_parent"
6-
android:layout_height="match_parent"
7-
android:orientation="vertical"
85
tools:context=".ResultFragment">
96

10-
<TextView
11-
android:id="@+id/won_lost"
7+
<data>
8+
<variable
9+
name="resultViewModel"
10+
type="com.hfad.guessinggame.ResultViewModel" />
11+
</data>
12+
13+
<LinearLayout
1214
android:layout_width="match_parent"
13-
android:layout_height="wrap_content"
14-
android:gravity="center"
15-
android:textSize="28sp" />
15+
android:layout_height="match_parent"
16+
android:orientation="vertical">
17+
18+
<TextView
19+
android:id="@+id/won_lost"
20+
android:layout_width="match_parent"
21+
android:layout_height="wrap_content"
22+
android:gravity="center"
23+
android:textSize="28sp"
24+
android:text="@{resultViewModel.result}"/>
1625

17-
<Button
18-
android:id="@+id/new_game_button"
19-
android:layout_width="wrap_content"
20-
android:layout_height="wrap_content"
21-
android:layout_gravity="center"
22-
android:text="@string/start_new_game" />
26+
<Button
27+
android:id="@+id/new_game_button"
28+
android:layout_width="wrap_content"
29+
android:layout_height="wrap_content"
30+
android:layout_gravity="center"
31+
android:text="@string/start_new_game" />
2332

24-
</LinearLayout>
33+
</LinearLayout>
34+
</layout>

playground/25-guessing-game/app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
<string name="start_new_game">Start new game</string>
44
<string name="guess_a_letter">Guess a letter</string>
55
<string name="guess">Guess!</string>
6+
<string name="lives_left">You have %d lives left</string>
7+
<string name="incorrect_guesses">Incorrect guesses: %s</string>
8+
<string name="finish_game">Finish Game</string>
69
</resources>

0 commit comments

Comments
 (0)