I want to use my data class AuthData in my MainViewModel.
package de.hsfl.appamigos.capturetheflag
import androidx.lifecycle.MutableLiveData
data class AuthData(var game: MutableLiveData<String>)
package de.hsfl.appamigos.capturetheflag
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
private val authData: MutableLiveData<AuthData> = MutableLiveData()
fun getGame(): LiveData<AuthData> = authData
fun setGame(newAuthData: AuthData) {
authData.value?.game = newAuthData.game
}
fun startNewGame(text: String) {
val newGame = MutableLiveData("1234")
val newAuthData = AuthData(newGame)
setGame(newAuthData)
}
}
When I try to observe changes in one of my Fragments it doesnt get notified.
package de.hsfl.appamigos.capturetheflag
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import de.hsfl.appamigos.capturetheflag.databinding.FragmentLobbyBinding
class LobbyFragment : Fragment() {
...
val mainViewModel: MainViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
// Inflate the layout for this fragment
//val root = inflater.inflate(R.layout.fragment_lobby, container, false)
val binding = FragmentLobbyBinding.inflate(inflater)
val naviGraph = findNavController()
mainViewModel.getGame().observe(viewLifecycleOwner) {
binding.textViewGameID.text = it.game.toString()
}
...
return binding.root;
//return inflater.inflate(R.layout.fragment_lobby, container, false)
}
}
I tried taking out the data class and only work with a Mutable and that worked so it's all connected kinda right. I guess it is because the authData doesn't change, but the attribute game does. How do I observe a change on the attribute itself? I cant work around the data class because that's demanded by my professor. I could use a normal class but I cant see how that would help.
You have a LiveData in a data class in a LiveData. That doesn't sound right.
Your data class should only contain simple classes, that is, Numbers or Strings etc., or other data classes. Also your data classes should be immutable when exposed from the view model, that is, they only contain val
properties. Your data class should look something like this:
data class AuthData(val game: String)
Adapt the view model to the changed data class like this:
class MainViewModel : ViewModel() {
private val authData: MutableLiveData<AuthData> = MutableLiveData()
fun getGame(): LiveData<AuthData> = authData
private fun setGame(newAuthData: AuthData) {
authData.value = newAuthData
}
fun startNewGame(text: String) {
val newGame = "1234"
val newAuthData = AuthData(newGame)
setGame(newAuthData)
}
}
Now everything should work fine.