Работаю над тем, чтобы заставить мое приложение работать, когда я поворачиваю экран. Я поместил свои вопросы и ответы в модель представления под названием QuizViewModel. Когда я пытаюсь запустить свое приложение, я получаю сообщение, что не могу запросить ViewModel до вызова onCreate и ошибки NullPointerException.
Я попытался вызвать вызов моей viewModel после onCreate и получить те же результаты. Я не знаю, что я мог сделать неправильно. Как я могу исправить эту проблему?
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
class QuizActivity : AppCompatActivity() {
private val defaultButtonColor = "#00a2ff"
private val selectedButtonColor = "#cb297b"
// view fields
private lateinit var questionTextView: TextView
private lateinit var answerButtonList: List<Button>
private lateinit var hintButton: Button
private lateinit var submitButton: Button
private val quizViewModel: QuizViewModel by lazy {
ViewModelProvider(this).get(QuizViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// initialize views
questionTextView = findViewById(R.id.question_text_view)
answerButtonList = listOf(
findViewById(R.id.answer_0_button),
findViewById(R.id.answer_1_button),
findViewById(R.id.answer_2_button),
findViewById(R.id.answer_3_button)
)
hintButton = findViewById(R.id.hint_button)
submitButton = findViewById(R.id.submit_button)
// attach listeners to answer buttons
for(index in answerButtonList.indices){
answerButtonList[index].setOnClickListener {
processAnswerButtonClick(index)
}
}
// attach listeners to hint button and submit button
hintButton.setOnClickListener {
processHintButtonClick()
}
submitButton.setOnClickListener {
processSubmitButtonClick()
quizViewModel.moveToNext()
}
refreshView()
}
private fun processAnswerButtonClick(answerIndex: Int) {
var answerList = quizViewModel.currentQuestionAnswer
val answer = answerList[answerIndex]
answerList.minus(answer).forEach { it.isSelected = false } //deselect all answers
answer.isSelected = !answer.isSelected //toggle clicked button
// refresh the view
refreshView()
}
private fun processHintButtonClick() {
// disable first enabled incorrect answer (even if selected)
var answerList = quizViewModel.currentQuestionAnswer
val incorrectAnswer = answerList.first {it.isEnabled && !it.isCorrect}
incorrectAnswer.isEnabled = false
incorrectAnswer.isSelected = false
refreshView()
}
private fun processSubmitButtonClick() {
var answerList = quizViewModel.currentQuestionAnswer
val correctAnswer = answerList.first { it.isSelected }
if (correctAnswer.isCorrect) {
Toast.makeText(this, R.string.correct_toast, Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, R.string.incorrect_toast, Toast.LENGTH_SHORT).show()
}
for( it in answerList) {
it.isEnabled = true
it.isSelected = false
}
refreshView()
}
private fun refreshView() {
var currentQuestionIndex = 0
currentQuestionIndex++
var question = quizViewModel.currentQuestionIndex
var answerList = quizViewModel.currentQuestionAnswer
questionTextView.setText(question)
for((answer, button) in answerList.zip(answerButtonList)){
button.setText(answer.textResId)
}
hintButton.setText(R.string.hint_button_text)
submitButton.setText(R.string.submit_button_text)
for ((answer, button) in answerList.zip(answerButtonList)) {
button.isEnabled = answer.isEnabled
button.isSelected = answer.isSelected
if (answer.isSelected) {
setButtonColor(button, selectedButtonColor)
} else {
setButtonColor(button, defaultButtonColor)
}
if (!answer.isEnabled) {
button.alpha = .5f
}
}
hintButton.isEnabled = answerList.any {it.isEnabled && !it.isCorrect}
submitButton.isEnabled = answerList.any {it.isSelected}
}
private fun setButtonColor(button: Button, colorString: String) {
button.backgroundTintList =
ColorStateList.valueOf(Color.parseColor(colorString))
button.setTextColor(Color.WHITE)
button.alpha = 1f
}
}