Gazza
October 18, 2021, 5:51am
1
Could you folks at Big Nerd Ranch please take a few moments and provide clarification on how to get through chapter 4 with Android Studio 2021.3.1. The lifecycle thing being depreciated issue needs to be clarified. I can’t figure it out on my own at this point, I bought your book to get started with this, not to hit a brick wall.
I’d like to think that I don’t have to toss your books in the trash a week after I buy them…
Gazza
October 25, 2021, 1:38am
2
This is what I ended up with…
package com.bignerdranch.android.geoquiz
import android.app.Activity
import android.app.ActivityOptions
import android.content.Intent
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityOptionsCompat
import androidx.lifecycle.ViewModelProvider
private const val TAG = "MainActivity"
private const val KEY_INDEX = "index"
private const val REQUEST_CODE_CHEAT = 0
private const val EXTRA_ANSWER_SHOWN = "com.bignerdranch.android.geoquiz.answer_shown"
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private lateinit var nextButton: ImageButton
private lateinit var prevButton: ImageButton
private lateinit var cheatButton: Button
private lateinit var questionTextView: TextView
private lateinit var quizViewModel: QuizViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate(Bundle?) called")
setContentView(R.layout.activity_main)
val currentIndex = savedInstanceState?.getInt(KEY_INDEX, 0) ?: 0
Log.d (TAG, "currentIndex = " + currentIndex)
//https://forums.bignerdranch.com/t/solution-to-deprecated-method-viewmodelproviders-of/16833/4
val factory = QuizViewModelFactory(currentIndex)
quizViewModel = ViewModelProvider(this@MainActivity, factory).get(QuizViewModel::class.java)
trueButton = findViewById(R.id.true_button)
falseButton = findViewById(R.id.false_button)
cheatButton = findViewById(R.id.cheat_button)
nextButton = findViewById(R.id.next_button)
prevButton = findViewById(R.id.prev_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()
}
prevButton.setOnClickListener { view: View ->
quizViewModel.moveToPrev()
updateQuestion()
}
cheatButton.setOnClickListener { view: View ->
val answerIsTrue =quizViewModel.currentQuestionAnswer
val intent = CheatActivity.newIntent(this@MainActivity, answerIsTrue)
//startActivityForResult (intent, REQUEST_CODE_CHEAT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val options = ActivityOptionsCompat.makeClipRevealAnimation(view,0,0,view.width,view.height)
resultLauncher.launch(intent, options)
} else {
resultLauncher.launch(intent)
}
}
updateQuestion()
}
// https://www.tutorialguruji.com/android/onactivityresult-method-is-deprecated-what-is-the-alternative/amp/
var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
//doSomeOperations()
quizViewModel.isCheater = data?.getBooleanExtra (EXTRA_ANSWER_SHOWN, false) ?: false
Log.d (TAG, "registerForActivityResult RESULT_OK is_cheater = " + quizViewModel.isCheater)
} else {
Log.d (TAG, "registerForActivityResult --NOT-- RESULT_OK")
}
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
Log.i (TAG, "onSaveInstanceState = " + quizViewModel.currentIndex)
savedInstanceState.putInt(KEY_INDEX, quizViewModel.currentIndex)
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart() called")
}
override fun onResume()
{
super.onResume()
Log.d(TAG, "onResume() called")
}
override fun onStop()
{
super.onStop()
Log.d(TAG, "onStop() called")
}
override fun onDestroy()
{
super.onDestroy()
Log.d(TAG, "onDestroy() called")
}
private fun updateQuestion()
{
val questionTextResId = quizViewModel.currentQuestionText
questionTextView.setText(questionTextResId)
}
private fun checkAnswer(userAnswer: Boolean)
{
val correctAnswer = quizViewModel.currentQuestionAnswer
val messageResId = when {
quizViewModel.isCheater -> R.string.judgement_toast
userAnswer == correctAnswer -> R.string.correct_toast
else -> R.string.incorrect_toast
}
val toast = Toast.makeText (this, messageResId, Toast.LENGTH_SHORT)
toast.setGravity (Gravity.BOTTOM,0,0)
toast.show()
}
}
Gazza
October 25, 2021, 1:49am
3
And my build.gradle file:
dependencies {
def activity_version = "1.3.1"
def fragment_version = "1.3.6"
def lifecycle_version = "2.4.0-rc01"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
// https://developer.android.com/jetpack/androidx/releases/lifecycle
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// ViewModel utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
implementation("androidx.activity:activity-ktx:$activity_version")
implementation("androidx.fragment:fragment-ktx:$fragment_version")
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
Gazza
October 25, 2021, 2:42am
4
And a view model provider factory in QuizViewModelFactory.kt
package com.bignerdranch.android.geoquiz
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class QuizViewModelFactory(private val initialQuestionIndex: Int) : ViewModelProvider.Factory
{
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return modelClass.getConstructor(Int::class.java).newInstance(initialQuestionIndex)
}
}