Неразрешенная ссылка (vars) в классе Fragment, MVVM, Viewmodel - PullRequest
1 голос
/ 06 мая 2020

Я слежу за бесплатным курсом UDACITY по разработке приложений Android с Kotlin, и на самом деле я нахожусь в части урока, посвященной Viewmodel / MVVM, ie реализуя классы Viewmodel для лучшего разделения проблем. Так или иначе, я заблокирован прямо сейчас. Я выполняю упражнение о создании класса Viewmodel и переносе переменных и функций из класса Fragment в этот только что созданный класс. Я шаг за шагом следую руководству, проверяю правильный ответ на предоставленном git diff, и я все еще оказываюсь заблокированным из-за неразрешенных ссылочных ошибок.

Перед изменением кода мне пришлось обновить файл модуля Gradle до использовать ViewModel

//ViewModel
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

Затем мне пришлось объявить свой объект Viewmodel в моем классе Fragment

gameViewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)

ViewModelProviders устарел, старый курс, мне пришлось изменить после поиска на

gameViewModel = ViewModelProvider(this).get(GameViewModel::class.java)

Кажется, это правильный способ, но у меня все еще остались некоторые Неразрешенные ссылки на переменные word (gameViewModel. word ) и оценка (gameViewModel. оценка ) в классе Fragment не удалось скомпилировать. Я не знаю, правильно ли я объявил объект Viewmodel или мне не хватает чего-то еще ...

У меня нет этой проблемы, Неразрешенная ссылка, с функциями класса ViewModel, ie gameViewModel.onCorrect () и gameViewModel.onSkip (). Кажется, что они правильно объявлены и вызваны в классе Fragment, что вызывает у меня вопрос о моих переменных, словах и оценках ...

My Fragment class

package com.example.android.guesstheword.screens.game

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.NavHostFragment.findNavController
import com.example.android.guesstheword.R
import com.example.android.guesstheword.databinding.GameFragmentBinding
import timber.log.Timber

class GameFragment : Fragment() {

private lateinit var binding: GameFragmentBinding

private lateinit var gameViewModel: GameViewModel



override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {

    // Inflate view and obtain an instance of the binding class
    binding = DataBindingUtil.inflate(
            inflater,
            R.layout.game_fragment,
            container,
            false
    )

    Timber.i("onCreateView  GameFragment called")
    gameViewModel = ViewModelProvider(this).get(GameViewModel::class.java)
    Timber.i("ViewModelProvider is called")

    binding.correctButton.setOnClickListener {
        gameViewModel.onCorrect()
        updateScoreText()
        updateWordText()
    }
    binding.skipButton.setOnClickListener {
        gameViewModel.onSkip()
        updateScoreText()
        updateWordText()
    }
    updateScoreText()
    updateWordText()
    return binding.root

}

/**
 * Called when the game is finished
 */
fun gameFinished() {
    val action = GameFragmentDirections.actionGameToScore(gameViewModel.score)
    findNavController(this).navigate(action)
}

/** Methods for updating the UI **/

private fun updateWordText() {
    binding.wordText.text = gameViewModel.word
}

private fun updateScoreText() {
    binding.scoreText.text = gameViewModel.score.toString()
}

override fun onDestroyView() {
    super.onDestroyView()
    Timber.i("onDestroyView GameFragment called")
}
}

My ViewModel class

package com.example.android.guesstheword.screens.game

import androidx.lifecycle.ViewModel
import timber.log.Timber

var word = ""
var score = 0

private lateinit var wordList: MutableList<String>

class GameViewModel: ViewModel() {
init {
    Timber.i("GameViewModel is created")
    resetList()
    nextWord()
}

override fun onCleared() {
    super.onCleared()
    Timber.i("GameViewModel is cleared")
}
/**
 * Resets the list of words and randomizes the order
 */


fun resetList() {
    wordList = mutableListOf(
            "queen",
            "hospital",
            "basketball",
            "cat",
            "change",
            "snail",
            "soup",
            "calendar",
            "sad",
            "desk",
            "guitar",
            "home",
            "railway",
            "zebra",
            "jelly",
            "car",
            "crow",
            "trade",
            "bag",
            "roll",
            "bubble"
    )
    wordList.shuffle()
}
/**
 * Moves to the next word in the list
 */
private fun nextWord() {
    //Select and remove a word from the list
    if (wordList.isEmpty()) {
        //gameFinished()
    } else {
        word = wordList.removeAt(0)
    }
}
/** Methods for buttons presses **/

fun onSkip() {
    score--
    nextWord()
}

fun onCorrect() {
    score++
    nextWord()
}
}

Где я облажался?

1 Ответ

0 голосов
/ 06 мая 2020

Переменные, к которым вы пытаетесь получить доступ, не входят в одну и ту же область:

var word = ""
var score = 0

private lateinit var wordList: MutableList<String>

class GameViewModel: ViewModel() {
...

ваши переменные объявлены вне ViewModel, добавьте их внутри класса GameViewModel, чтобы сделать их экземпляром переменные:

class GameViewModel: ViewModel() {
var word = ""
var score = 0
...
}
...