带有SavedState的AndroidViewModel

问题描述 投票:1回答:1

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

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

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

我认为这个问题可能会减少为:

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

所以,为了在SavedStateHandle中也有一个MyViewModel,我该如何修改片段中的调用(示例代码中的B1行)?我是否需要对工厂SavedStateViewModelFactory的明确调用?那到底是什么样子? (我还是Kotlin / Android的新手,之前从未在工厂工作过)

android factory android-architecture-components android-viewmodel
1个回答
1
投票

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

在AndroidX-Activity 1.2.0中,他们添加了一个名为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,我可以将其换成SavedStateViewModelFactory中的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的自动实例化:

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

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

请注意,application, savedStateHandle应预期顺序为SavedStateViewModelFactory

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

© www.soinside.com 2019 - 2024. All rights reserved.