如何在ViewPager子Fragment中共享父Fragment的ViewModel?
问题原因&解决方案
你当前的实现已经覆盖了核心逻辑,出现ViewModel重复创建的问题可以按以下步骤排查修正:
1. 修正ViewPagerAdapter构造逻辑
优先使用FragmentStateAdapter原生提供的父Fragment构造方法,内部会自动绑定父Fragment的childFragmentManager和生命周期,避免手动传参出错:
class ReservationMainViewPagerAdapter( parentFragment: Fragment ) : FragmentStateAdapter(parentFragment) { private var pageCount = 4 override fun getItemCount(): Int = pageCount override fun createFragment(position: Int): Fragment = when (position) { 0 -> DataSheetFragment() 1 -> ReservationFragment() 2 -> DocumentUploadFragment() 3 -> NoteFragment() else -> throw IllegalArgumentException("invalid view position: $position") } fun disableLastTwoPage() { pageCount = 2 notifyDataSetChanged() } fun enableAllPage() { pageCount = 4 notifyDataSetChanged() } }
父Fragment中初始化Adapter的代码简化为:
adapter = ReservationMainViewPagerAdapter(this)
2. 确认父Fragment正确初始化共享ViewModel
父Fragment必须自身先通过by viewModels()初始化ReservationMainViewModel,才能保证ViewModelStore中存在对应实例:
@AndroidEntryPoint class ReservationParentFragment : BaseFragment() { // 父Fragment初始化共享ViewModel,生命周期和父Fragment绑定 private val reservationMainViewModel: ReservationMainViewModel by viewModels() // 后续正常初始化ViewPager即可 }
3. 优化子Fragment的ViewModel获取逻辑
用requireParentFragment()替代强制类型转换,避免空指针风险,只要父Fragment是同一个实例,拿到的ViewModel就是同一个:
@AndroidEntryPoint class DataSheetFragment : BaseBindingFragment<FragmentDataSheetBinding,DataSheetViewModel>() { private val viewModel: DataSheetViewModel by viewModels() // 明确指定ViewModel的所有者为父Fragment private val reservationMainViewModel: ReservationMainViewModel by viewModels( ownerProducer = { requireParentFragment() } ) }
4. Hilt相关校验
确认ReservationMainViewModel添加了Hilt必要注解,否则Hilt会生成独立实例:
@HiltViewModel // 必须加此注解 class ReservationMainViewModel @Inject constructor( // 你的依赖项 ) : ViewModel() { // 业务逻辑 }
内容的提问来源于stack exchange,提问作者Andreas1234
相关产品推荐
相关产品推荐

