Fragment where the game is played, contains the game logic.
*/
class GameFragment : Fragment() {
private val viewModel: GameViewModel by viewModels()
// Binding object instance with access to the views in the game_fragment.xml layout
private lateinit var binding: GameFragmentBinding
// Create a ViewModel the first time the fragment is created.
// If the fragment is re-created, it receives the same GameViewModel instance created by the
// first fragment
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout XML file and return a binding object instance
binding = GameFragmentBinding.inflate(inflater, container, false)
Log.d("Game Fragment", "GameFragment created/re-created!")
Log.d("GameFragment","Word:${viewModel.currentScrambledWord} " +
" Score: ${viewModel.score} WordCount: ${viewModel.currentWordCount}")
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Setup a click listener for the Submit and Skip buttons.
binding.submit.setOnClickListener { onSubmitWord() }
binding.skip.setOnClickListener { onSkipWord() }
// Update the UI
viewModel.currentScrambledWord.observe(viewLifecycleOwner,
{newWord ->
binding.textViewUnscrambledWord.text = newWord
})
viewModel.score.observe(viewLifecycleOwner,
{newScore ->
binding.score.text = getString(R.string.score, newScore)
})
viewModel.currentWordCount.observe(viewLifecycleOwner,
{newWordCount ->
binding.wordCount.text =
getString(R.string.word_count, newWordCount, MAX_NO_OF_WORDS)
})
}
/*
Checks the user's word, and updates the score accordingly.
Displays the next scrambled word.
*/
private fun onSubmitWord() {
val playerWord = binding.textInputEditText.text.toString()
Skips the current word without changing the score.
Increases the word count.
*/
private fun onSkipWord() {
if(viewModel.nextWord()){
setErrorTextField(false)
}else{
showFinalScoreDialog()
}
}
/*
Gets a random word for the list of words and shuffles the letters in it.
*/
private fun getNextScrambledWord(): String {
val tempWord = allWordsList.random().toCharArray()
tempWord.shuffle()
return String(tempWord)
}
/*
Re-initializes the data in the ViewModel and updates the views with the new data, to
restart the game.
*/
private fun restartGame() {
viewModel.reinitializeData()
setErrorTextField(false)
}
/*
Exits the game.
*/
private fun exitGame() {
activity?.finish()
}
/*
Sets and resets the text field error status.
*/
private fun setErrorTextField(error: Boolean) {
if (error) {
binding.textField.isErrorEnabled = true
binding.textField.error = getString(R.string.try_again)
} else {
binding.textField.isErrorEnabled = false
binding.textInputEditText.text = null
}
}
https://user-images.githubusercontent.com/79910450/149629723-511c1ce8-b590-4d64-8f47-b7dbfb5cca00.mp4
URL of codelab https://developer.android.com/codelabs/basic-android-kotlin-training-livedata?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-kotlin-unit-3-pathway-3%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-training-livedata#5
In which task and step of the codelab can this issue be found? Running App and Viewing LiveData.
Describe the problem Score is not updating in the app, but word count is updating no problem, I've attached a video to the issue please help!
Steps to reproduce?
Versions Android Studio version: Arctic Fox | 2020.3.1 Patch 4 API version of the emulator: 31
Additional information Include screenshots if they would be useful in clarifying the problem. Here's the code:
GameFragment.kt `/*
package com.example.android.unscramble.ui.game
import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import com.example.android.unscramble.R import com.example.android.unscramble.databinding.GameFragmentBinding import com.google.android.material.dialog.MaterialAlertDialogBuilder
/**
Fragment where the game is played, contains the game logic. */ class GameFragment : Fragment() {
private val viewModel: GameViewModel by viewModels()
// Binding object instance with access to the views in the game_fragment.xml layout private lateinit var binding: GameFragmentBinding
// Create a ViewModel the first time the fragment is created. // If the fragment is re-created, it receives the same GameViewModel instance created by the // first fragment
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // Inflate the layout XML file and return a binding object instance binding = GameFragmentBinding.inflate(inflater, container, false) Log.d("Game Fragment", "GameFragment created/re-created!") Log.d("GameFragment","Word:${viewModel.currentScrambledWord} " + " Score: ${viewModel.score} WordCount: ${viewModel.currentWordCount}") return binding.root }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState)
}
/*
Displays the next scrambled word. */ private fun onSubmitWord() { val playerWord = binding.textInputEditText.text.toString()
if(viewModel.isUserWordCorrect(playerWord)) { setErrorTextField(false) if (!viewModel.nextWord()) { showFinalScoreDialog() } }else{ setErrorTextField(true) } }
/*
Increases the word count. */ private fun onSkipWord() { if(viewModel.nextWord()){ setErrorTextField(false)
}else{ showFinalScoreDialog() } }
/*
/*
/*
/*
/*
private fun showFinalScoreDialog(){ MaterialAlertDialogBuilder(requireContext()) .setTitle(getString(R.string.congratulations)) .setMessage(getString(R.string.you_scored, viewModel.score.value)) .setCancelable(false) .setPositiveButton(getString(R.string.playagain)){ , -> restartGame() } .setNegativeButton(getString(R.string.exit)){ , _ -> exitGame() } .show() }
override fun onDetach() { super.onDetach() Log.d("GameFragment", "GameFragment destroyed!") } } ` GameViewModel.kt
`package com.example.android.unscramble.ui.game
import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel
class GameViewModel : ViewModel() { private val _score = MutableLiveData(0) val score: LiveData
get() = _score
} `