First I removed the var isCheater from QuizViewModel.kt, instead of using it, I decided to use the structure very similar from Challenge from Chapter 3, and using the wasAnswered variable from Question.kt, and mark each question cheated (marked as true). So, knowing the user cheated in some specific question, in this way in onActivityForResult in MainActivity.kt:
quizViewModel.questionBank[quizViewModel.currentIndex].wasAnswered =
data?.getBooleanExtra(EXTRA_ANSWER_SHOWN, false) ?: false
The final Result is:
MainActivity.kt
private const val TAG = "MainActivity"
private const val BUNDLE_KEY_INDEX = "index"
private const val REQUEST_CODE_CHEAT = 0
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private lateinit var cheatButton: Button
private lateinit var nextButton: Button
private lateinit var questionTextView: TextView
private val quizViewModel: QuizViewModel by lazy {
ViewModelProviders.of(this).get(QuizViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate(Bundle?) called")
setContentView(R.layout.activity_main)
val currentIndex = savedInstanceState?.getInt(BUNDLE_KEY_INDEX, 0) ?: 0
quizViewModel.currentIndex = currentIndex
trueButton = findViewById(R.id.true_button)
falseButton = findViewById(R.id.false_button)
cheatButton = findViewById(R.id.cheat_button)
nextButton = findViewById(R.id.next_button)
questionTextView = findViewById(R.id.question_text_view);
trueButton.setOnClickListener { view: View ->
checkAnswer(true)
}
falseButton.setOnClickListener { view: View ->
checkAnswer(false)
}
nextButton.setOnClickListener { view: View ->
quizViewModel.moveToNext()
updateQuestion()
}
cheatButton.setOnClickListener { view: View ->
val answerIsTrue = quizViewModel.currentQuestionAnswer
val intent = CheatActivity.newIntent(this@MainActivity, answerIsTrue)
startActivityForResult(intent, REQUEST_CODE_CHEAT)
}
updateQuestion()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != Activity.RESULT_OK) {
return
}
if (requestCode == REQUEST_CODE_CHEAT) {
quizViewModel.questionBank[quizViewModel.currentIndex].wasAnswered =
data?.getBooleanExtra(EXTRA_ANSWER_SHOWN, false) ?: false
}
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart() called")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume() called")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause() called")
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putInt(BUNDLE_KEY_INDEX, quizViewModel.currentIndex)
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop() called")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy() called")
}
private fun updateQuestion() {
Log.d(TAG, "Updating question text", Exception())
val questionTextResId = quizViewModel.currentQuestionText
questionTextView.setText(questionTextResId)
}
private fun checkAnswer(userAnswer: Boolean) {
val correctAnswer = quizViewModel.currentQuestionAnswer
val messageResId = when {
quizViewModel.questionBank[quizViewModel.currentIndex].wasAnswered -> R.string.judgment_toast
userAnswer == correctAnswer -> R.string.correct_toast
else -> R.string.incorrect_toast
}
Toast.makeText(this, messageResId, Toast.LENGTH_SHORT).show()
}
CheatActivity.kt
const val EXTRA_ANSWER_SHOWN = "com.rpizzolato.geoquiz.answer_shown"
private const val EXTRA_ANSWER_IS_TRUE = "com.rpizzolato.geoquiz.answer_is_true"
private const val KEY_WAS_CHEATED = "was_cheated"
class CheatActivity : AppCompatActivity() {
private lateinit var answerTextView: TextView
private lateinit var showAnswerButton: Button
private var answerIsTrue = false
private var wasCheated = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cheat)
wasCheated = savedInstanceState?.getBoolean(KEY_WAS_CHEATED, false) ?: false
setAnswerShownResult(wasCheated)
answerIsTrue = intent.getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false)
answerTextView = findViewById(R.id.answer_text_view)
showAnswerButton = findViewById(R.id.show_answer_button)
showAnswerButton.setOnClickListener {
wasCheated = true
setAnswerShownResult(true)
fillTextIfCheated()
}
fillTextIfCheated()
}
private fun fillTextIfCheated() {
if (wasCheated) {
val answerText = when {
answerIsTrue -> R.string.true_button
else -> R.string.false_button
}
answerTextView.setText(answerText)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(KEY_WAS_CHEATED, wasCheated)
}
private fun setAnswerShownResult(isAnswerShown: Boolean) {
if (wasCheated) {
val data = Intent().apply {
putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown)
}
setResult(Activity.RESULT_OK, data)
}
}
companion object {
fun newIntent(packageContext: Context, answerIsTrue: Boolean): Intent {
return Intent(packageContext, CheatActivity::class.java).apply {
putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue)
}
}
}
}
QuizViewModel.kt
private const val TAG = "QuizViewModel"
class QuizViewModel: ViewModel() {
val questionBank = listOf(
Question(R.string.question_australia, true),
Question(R.string.question_oceans, true),
Question(R.string.question_mideast, false),
Question(R.string.question_americas, false),
Question(R.string.question_asia, true))
var currentIndex = 0
val currentQuestionAnswer: Boolean get() = questionBank[currentIndex].answer
val currentQuestionText: Int get() = questionBank[currentIndex].textResId
fun moveToNext() {
currentIndex = (currentIndex + 1) % questionBank.size
}
}
Question.kt
data class Question (@StringRes
val textResId: Int,
val answer: Boolean,
var wasAnswered: Boolean = false)
Please, feel free to comment this solution, I appreciate it.