简体   繁体   English

ViewModelProvider.Factory 总是返回一个视图模型

[英]ViewModelProvider.Factory always return one viewmodel

I have a TabLayout , contains three Fragment (Created by same instance) by SectionsPagerAdapter .我有一个TabLayout ,包含SectionsPagerAdapter的三个Fragment (由同一实例创建)。 Inside the fragment, I try with ViewModelProvider.Factory to create independent viewmodel, however, I found all fragments always update content together with same data.在片段内部,我尝试使用ViewModelProvider.Factory创建独立的视图模型,但是,我发现所有片段总是与相同的数据一起更新内容。

I have debugged and found it always return the same viewmodel even with difference BillType , and something's weird that when enterence into activity, the Factory.create is only invoked once.我已经调试过,发现即使有不同的BillType ,它也总是返回相同的视图模型,而且有些奇怪的是,当进入活动时, Factory.create只被调用一次。

// Log
D/BillType: OUTCOME
D/Factory crate BillType: OUTCOME
D/ViewModel Init BillType: OUTCOME
D/viewModel Bill:BillType: OUTCOME
D/BillType: INCOME
D/viewModel Bill:BillType: OUTCOME
D/BillType: TRANSFER
D/viewModel Bill:BillType: OUTCOME

I cannot figure out where is wrong, same code runs correctly before.我不知道哪里错了,相同的代码之前运行正确。

class BillViewModel(billType: BillType): ViewModel() {
    val bill: MutableLiveData<Bill> = MutableLiveData()

    init {
        Log.d("ViewModel Init BillType", billType.toString())
        bill.value = Bill.QBill().apply {
            type = billType
        }
    }

    class NewBillViewModelFactory(val billType: BillType): ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            Log.d("Factory crate BillType", billType.toString())
            return modelClass.getConstructor(BillType::class.java)
                .newInstance(billType)
        }
    }
}
enum class BillType(val type: Int) {
    OUTCOME(0),
    INCOME(1),
    TRANSFER(2);
}
class NewBillFragment: BaseFragment() {
    ...
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        billType = BillType.values()[arguments?.getInt(BILLTYPE, 0) ?: 0]
        Log.d("BillType", billType.toString())
        viewModel = ViewModelProvider(requireActivity(), NewBillViewModel.NewBillViewModelFactory(billType))[NewBillViewModel::class.java]
        Log.d("viewModel Bill:BillType", viewModel.bill.value?.type.toString())
        _binding = FragmentBillNewBinding.inflate(layoutInflater, container, false)
        with(binding) {
            data = viewModel
            lifecycleOwner = activity
        ... ui ...
        return binding.root
    }

    companion object {
        private const val BILLTYPE = "billtype"

        @JvmStatic
        fun newInstance(billType: Int): NewBillFragment {
            return NewBillFragment().apply {
                arguments = Bundle().apply {
                    putInt(BILLTYPE, billType)
                }
            }
        }
    }
}
class SectionsPagerAdapter(private val context: Context, fm: FragmentManager)
    : FragmentPagerAdapter(fm) {

    override fun getItem(position: Int): Fragment = BillFragment.newInstance(position)

    override fun getPageTitle(position: Int): CharSequence = context.resources.getString(TAB_TITLES[position])

    override fun getCount(): Int = 3
}

Because you are creating a Shared ViewModel with requireActivity() .因为您正在使用requireActivity()创建共享ViewModel So it will return ViewModel with reference to Activity not Fragment.所以它会参考Activity而不是 Fragment 返回ViewModel

If you want to keep ViewModel Fragment scoped Then you should pass Fragment as ViewModelStoreOwner .如果您想保持ViewModel Fragment 的范围,那么您应该将Fragment作为ViewModelStoreOwner传递。

        viewModel = ViewModelProvider(this, NewBillViewModel.NewBillViewModelFactory(billType))[NewBillViewModel::class.java]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取ViewModel ViewModelProvider.Factory和应用程序上下文 - Get ViewModel ViewModelProvider.Factory and Application Context 为什么为我的viewModel类实现ViewModelProvider.Factory很重要? - Why it is important to implement a ViewModelProvider.Factory for my viewModel class? 匕首2 viewmodels和ViewModelProvider.Factory - dagger 2 viewmodels and ViewModelProvider.Factory 将ViewModelProvider.Factory的提供程序注入espresso测试 - Inject provider of ViewModelProvider.Factory into esspresso test 如何将 ViewModelProvider.Factory 注入片段 - How to inject ViewModelProvider.Factory into a fragment Dagger 2 ViewModelProvider.Factory绑定多次 - Dagger 2 ViewModelProvider.Factory bound multiple times ViewModelProvider.Factory 和 ViewModelProvider.NewInstanceFactory 有什么区别? - What are the differences between ViewModelProvider.Factory and ViewModelProvider.NewInstanceFactory? 使用Android上的Dagger和Java,ViewModelProvider.Factory在片段上保持为空 - ViewModelProvider.Factory remains null on fragment using Dagger and Java on Android Dagger2,在依赖组件中为 ViewModelProvider.Factory 添加绑定 - Dagger2, adding a binding for ViewModelProvider.Factory in a dependant component 执行 ViewModelProvider.Factory 并且我收到空指针异常 - Impementing a ViewModelProvider.Factory and I am getting a null pointer exeception
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM