Android ViewModel Observers 直到方向改变才工作(ViewModel 工作,但更改为 LiveData 会导致问题)

Posted

技术标签:

【中文标题】Android ViewModel Observers 直到方向改变才工作(ViewModel 工作,但更改为 LiveData 会导致问题)【英文标题】:Android ViewModel Observers not working until orientation change (ViewModel works, but changing to LiveData causes the problem) 【发布时间】:2022-01-17 21:44:35 【问题描述】:

我一直在尝试制作一个应用程序,它将我的值加倍或加倍到 2 个文本视图中,当我使用 viewModel 时,它在所有配置更改中都幸存下来。当我将结果类型更改为 MutableLiveData 时,textView 值不会改变,直到我按下按钮后旋转手机。这是我的 MainFragment

class MainFragment : Fragment() 
private var _binding: MainFragmentBinding? = null
private val binding get() = _binding!!

companion object 
    fun newInstance() = MainFragment()


private lateinit var viewModel: MainViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View 
    _binding = MainFragmentBinding.inflate(inflater, container, false)
    return binding.root


override fun onActivityCreated(savedInstanceState: Bundle?) 
    super.onActivityCreated(savedInstanceState)
    viewModel = ViewModelProvider(this)[MainViewModel::class.java]

    binding.textView.text = viewModel.getResults().toString()
    binding.textView2.text = viewModel.getResults().toString()


    val resultsObserver = Observer<List<Float?>>
        binding.textView.text = it[0].toString()
        binding.textView2.text = it[1].toString()
    

    viewModel.getResults().observe(viewLifecycleOwner, resultsObserver)

    binding.action.setOnClickListener 

        if(binding.editTextNumberDecimal.text.isNotEmpty())
            viewModel.setValues(binding.editTextNumberDecimal.text.toString())
        else
            binding.textView.text = getString(R.string.no)
            binding.textView2.text = getString(R.string.no1)
        
    

这是我的视图模型

class MainViewModel : ViewModel() 
private var input = ""

private var doubleValue = 0f

private var tripleValue = 0f

fun setValues(value: String)
    input = value
    doubleValue = input.toFloat() * 2
    tripleValue = input.toFloat() * 3


fun getResults(): MutableLiveData<List<Float?>> = MutableLiveData(listOf(doubleValue, tripleValue))

【问题讨论】:

欢迎来到 SO。 LiveData 是一个值持有者,为了使用它,您必须观察它,然后更新它的值。我建议您花几分钟时间阅读the official documentation,其中包含底部的一个简单示例。简而言之,您需要执行mutableld.postValue(xxx)(例如)。并且观察到的 liveData 会触发。 很多事情都搞清楚了,谢谢!另外,我很感激欢迎 【参考方案1】:

MutableLiveData 不会自动响应您通过setValues 设置的更改值。 您需要通过setValue() 显式更新MutableLiveData 中的值。

要实现这一点,我建议您将您的 MutableLiveData 存储在您的 ViewModel 字段中以便能够访问它。

例如这样:

class MainViewModel : ViewModel() 

    private var input = ""

    private var doubleValue = 0f

    private var tripleValue = 0f

    private val results = MutableLiveData(listOf(doubleValue, tripleValue))

    fun setValues(value: String)
        input = value
        doubleValue = input.toFloat() * 2
        tripleValue = input.toFloat() * 3
        // This updates the value inside your LiveData
        results.value = listOf(doubleValue, tripleValue)
    

    fun getResults(): LiveData<List<Float?>> = results

【讨论】:

fun getResults(): MutableLiveData&lt;List&lt;Float?&gt;&gt; = results -> fun getResults(): LiveData&lt;List&lt;Float?&gt;&gt; = results ;) 你不应该暴露“可变”的 liveData。 谢谢@jodoll。我还没有足够的声誉来投票,但是您的解决方案非常有效!干杯 @MartinMarconcini 你说的很对,我尽量减少改动,但我会添加这个。

以上是关于Android ViewModel Observers 直到方向改变才工作(ViewModel 工作,但更改为 LiveData 会导致问题)的主要内容,如果未能解决你的问题,请参考以下文章

Android官方架构组件之LiveData + ViewModel + Room 源码分析

2022年Android面试之Jetpack(AAC框架)篇

Android Compose 新闻AppViewModelHlit数据流

如何将editText值传递给viewModel和Livedata(Kotlin)

如何避免两次调用observe()?

Android 回收站视图更新