具有SavedState的AndroidViewModel [英] AndroidViewModel with SavedState

查看:143
本文介绍了具有SavedState的AndroidViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在应用程序上下文中使用AndroidViewModelSavedStateHandle.我已经在应用程序上下文中使用它,但是我无法在其中添加SavedStateHandle.

I need to use an AndroidViewModel with application context and a SavedStateHandle. I have it already working with application context, but I fail adding a SavedStateHandle to it.

这就是我所拥有的,只有应用程序上下文:

This is what I have, with only the application context:

// A1. get ViewModel in Fragment
val viewModel = ViewModelProvider(viewLifecycleOwner).get(MyViewModel::class.java)

// A2. MyViewModel derives from my custom BaseAndroidViewModel
class MyViewModel(application: Application) :BaseAndroidViewModel(application)

// A3. BaseAndroidViewModel in turn derives from AndroidViewModel
open class BaseAndroidViewModel(application: Application) : AndroidViewModel(application)

对于这个问题,我认为可以将其简化为:

I assume for this question this could likely be reduced to:

// B1. get ViewModel in Fragment
val viewModel = ViewModelProvider(viewLifecycleOwner).get(MyViewModel::class.java)

// B2. BaseAndroidViewModel in turn derives from AndroidViewModel
class MyViewModel(application: Application) : AndroidViewModel(application) 

那么,对于在MyViewModel中也有SavedStateHandle的情况,我将如何修改该片段中的调用(示例代码中的B1行)?我是否需要显式调用工厂SavedStateViewModelFactory?那到底是什么样子? (我还是Kotlin/Android的新手,我以前从未在工厂工作过)

So, for also having a SavedStateHandle in MyViewModel, how would I have to modify the call in the fragment (line B1 in the example code) ? Do I need an explicit call to the factory SavedStateViewModelFactory? How exactly would that look like? (I am still new to Kotlin/Android, I've never worked with a factory before)

推荐答案

编辑:在最终版本的AndroidX-Activity 1.2.0AndroidX-Fragment 1.1.0中,他们将SavedStateViewModelFactory设置为AppCompatActivity/中的默认工厂.片段,因此不需要覆盖默认工厂(这是该答案的后半部分所做的事情.)

in the final release of AndroidX-Activity 1.2.0 and AndroidX-Fragment 1.1.0, they made SavedStateViewModelFactory the default factory in AppCompatActivity/Fragment, so it is not needed to override the default factory (which is what the second half of this answer does.)

更新然后使用

class MyViewModel(val savedStateHandle: SavedStateHandle): ViewModel()

class MyAndroidViewModel(application: Application, val savedStateHandle: SavedStateHandle): AndroidViewModel(application)

应该工作.

原始:

我将如何修改片段中的调用(示例代码中的B1行)?我是否需要对工厂SavedStateViewModelFactory的显式调用?到底是什么样子?

how would I have to modify the call in the fragment (line B1 in the example code) ? Do I need an explicit call to the factory SavedStateViewModelFactory? How exactly would that look like?

在AndroidX-Activity 1.2.0中,他们添加了一个名为getDefaultViewModelProviderFactory()的新方法:

In AndroidX-Activity 1.2.0, they added a new method called getDefaultViewModelProviderFactory():

+    @NonNull
+    @Override
+    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
+        if (getApplication() == null) {
+            throw new IllegalStateException("Your activity is not yet attached to the "
+                    + "Application instance. You can't request ViewModel before onCreate call.");
+        }
+        return ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication());
+    }
+

这意味着如果我有BaseActivityBaseFragment,我可以将其从viewmodel-savedstate换成SavedStateViewModelFactory:

Which means if I have a BaseActivity or a BaseFragment, I can swap this out for the SavedStateViewModelFactory from viewmodel-savedstate:

class BaseActivity: AppCompatActivity() {
    override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory = 
        SavedStateViewModelFactory(application, this, intent?.extras ?: Bundle())
}

class BaseFragment: Fragment() {
    override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory = 
        SavedStateViewModelFactory(requireActivity().application, this, arguments ?: Bundle())
}

一旦有了,您就可以依靠将SavedStateHandle作为其参数之一的ViewModel的自动实例化:

Once you have that, you can rely on the automatic instantiation of ViewModel with SavedStateHandle as one of their arguments:

class MyViewModel(val savedStateHandle: SavedStateHandle): ViewModel()

class MyAndroidViewModel(application: Application, val savedStateHandle: SavedStateHandle): AndroidViewModel(application)

请注意,SavedStateViewModelFactory应符合订单application, savedStateHandle.

但是,如果您确实需要自定义参数,则在调用ViewModelProvider(viewModelStoreOwner).get(...)方法时必须提供object: AbstractSavedStateViewModelFactory

However, if you do need custom arguments on top of that, then you'd have to provide a object: AbstractSavedStateViewModelFactory when you invoke the ViewModelProvider(viewModelStoreOwner).get(...) method

这篇关于具有SavedState的AndroidViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆