代码之家  ›  专栏  ›  技术社区  ›  Max Gordon Günsel

带有数据类的LiveData未在ViewModel中更新

  •  1
  • Max Gordon Günsel  · 技术社区  · 2 年前

    我想在MainViewModel中使用我的数据类AuthData。

    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)
        }
    }
    

    当我试图观察我的一个片段的变化时,它不会得到通知。

    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)
        }
    }
    

    我试着去掉数据类,只使用Mutable,这很有效,所以所有的连接都很好。 我想这是因为authData不会改变,但属性游戏会改变。如何观察属性本身的变化? 我不能围绕数据类工作,因为这是我的教授要求的。我可以使用普通的课程,但我看不出这会有什么帮助。

    2 回复  |  直到 2 年前
        1
  •  0
  •   tyg    2 年前

    您在LiveData的数据类中有一个LiveData。这听起来不对。

    您的数据类应该只包含简单的类,即数字或字符串等,或者其他数据类。此外,当从视图模型中公开时,数据类应该是不可变的,也就是说,它们只包含 val 属性。您的数据类应该如下所示:

    data class AuthData(val game: String)
    

    使视图模型适应更改后的数据类,如下所示:

    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)
        }
    }
    

    现在一切都应该正常。

        2
  •  0
  •   dominicoder    2 年前

    我想这是因为authData不会改变,但属性游戏会改变。

    精确地

    如何观察属性本身的变化?

    观察属性本身。

    mainViewModel.getGame().game.observe(viewLifecycleOwner) {
        binding.textViewGameID.text = it.game.toString()
    }
    

    或者更新当前观察到的整个对象。

    fun setGame(newAuthData: AuthData) {
        //authData.value?.game = newAuthData.game
        authData.value = newAuthData
    }
    

    附言-你的方法名称很混乱。获取并设置“游戏”获取并设置一个“AuthData”,它本身就有一个“游戏”?如果您正在获取和设置“AuthData”,只需调用它 getAuthData 和 setAuthData .