使用 Factory 创建共享 ViewModel

2023-12-09

我有一个包含 3 个选项卡的 TabLayout 的文档片段:

TabRulesFragment, TabProceduresFragment, TabGuidanceFragment

在 DocumentsFragment 中,我使用工厂初始化共享 viewModel DocumentsSharedViewModel:

class DocumentsFragment : Fragment() {

    private lateinit var sharedViewModel: DocumentsSharedViewModel
    private lateinit var viewPager2: ViewPager2
    private lateinit var documentsCollectionAdapter: DocumentsCollectionAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val program = DocumentsFragmentArgs.fromBundle(requireArguments()).program
        val name = DocumentsFragmentArgs.fromBundle(requireArguments()).name

        val viewModelFactory = DocumentsSharedViewModelFactory(program, name)
        sharedViewModel = ViewModelProvider(this, viewModelFactory)[DocumentsSharedViewModel::class.java]

在文档片段和 3 个选项卡片段之间共享数据。当我尝试连接到选项卡片段之一(例如 TabRulesFragment)中的共享 viewModel 时:

class TabRulesFragment : Fragment() {

    private lateinit var tabRulesRecyclerView: RecyclerView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        val sharedViewModel : DocumentsSharedViewModel by viewModels()
        val binding = TabRulesFragmentBinding.inflate(layoutInflater)
        binding.viewModel = sharedViewModel

我收到错误消息,无法创建 DocumentsSharedViewModel 的实例:

java.lang.RuntimeException: Cannot create an instance of class com.smellydogcoding.westvirginiaelectronicfieldguide.ui.documents.DocumentsSharedViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:188)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)
        at com.smellydogcoding.westvirginiaelectronicfieldguide.ui.documents.rulesTab.TabRulesFragment.onCreateView$lambda-0(TabRulesFragment.kt:30)
        at com.smellydogcoding.westvirginiaelectronicfieldguide.ui.documents.rulesTab.TabRulesFragment.onCreateView(TabRulesFragment.kt:32)

我假设 viewModelProvider 正在寻找工厂(它在 TabRulesFragment 中不存在,因为它在 DocumentsFragment 中),并在找不到它时抛出错误。有没有办法使用共享数据模型中的数据而不创建它的另一个实例?


如果您希望将 ViewModel 范围限定为可以在片段之间共享的所属 Activity,则可以使用以下命令在两个片段中获取它。

val sharedModel: DocumentsSharedViewModel by activityViewModels()

根据docs,其中有一个简单的示例,其中两个片段都可以访问相同的 ViewModel

class ListFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //...
    }
}

class DetailFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //...
    }
}

正如评论中所指出的,如果您希望 ViewModel 的范围保持在父片段您可以使用它来在子片段中访问它,而不是使用活动范围

val sharedModel: DocumentsSharedViewModel by viewModels({ requireParentFragment() })
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Factory 创建共享 ViewModel 的相关文章

随机推荐