【发布时间】:2021-06-17 14:17:33
【问题描述】:
我有一个TabLayout,包含三个Fragment(由同一实例创建)SectionsPagerAdapter。在片段内部,我尝试使用ViewModelProvider.Factory 创建独立的视图模型,但是,我发现所有片段总是与相同的数据一起更新内容。
我已经调试过,发现它总是返回相同的视图模型,即使 有区别
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
我不知道哪里错了,之前的代码运行正常。
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
}
【问题讨论】:
标签: android android-fragments mvvm viewmodel android-viewmodel