无法通过Hilt将Fragment的Bundle参数传入ViewModel的SavedStateHandle
问题解决:Fragment参数无法传入ViewModel的SavedStateHandle
错误原因
- 第二个Fragment初始化
CustomerViewModel时,默认的by viewModels()不会自动将Fragment的arguments数据同步到ViewModel的SavedStateHandle中,导致SavedStateHandle里没有对应参数。 - ViewModel中
getArgs的初始化逻辑错误:一次性读取SavedStateHandle["customer"]的初始值存入MutableLiveData,但此时SavedStateHandle中还没有该数据,且无法监听后续数据变化。
修正步骤
步骤1:修改ViewModel,用SavedStateHandle自带的LiveData监听数据
替换手动创建MutableLiveData的逻辑,直接使用SavedStateHandle.getLiveData()来自动同步和监听数据:
@HiltViewModel class CustomerViewModel @Inject constructor( private val cusomerRepository: CusomerRepository, val savedStateHandle: SavedStateHandle // 改为val,允许Fragment访问 ) : ViewModel() { val customerList: LiveData<List<CustomerModel>> // 通过SavedStateHandle获取LiveData,自动同步数据变化 val getArgs: LiveData<CustomerModel?> = savedStateHandle.getLiveData("customer") }
步骤2:在第二个Fragment中手动将arguments存入SavedStateHandle
在onCreateView中取出Fragment参数,存入ViewModel的SavedStateHandle:
@AndroidEntryPoint class OrderReview : Fragment() { private lateinit var binding: FragmentOrderReviewBinding private val customerViewModel: CustomerViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentOrderReviewBinding.inflate(inflater, container, false) binding.argsModel = customerViewModel binding.lifecycleOwner = viewLifecycleOwner // 将Fragment参数写入ViewModel的SavedStateHandle arguments?.getParcelable<CustomerModel>("customer")?.let { customer -> customerViewModel.savedStateHandle.set("customer", customer) } return binding.root } }
额外注意事项
- 确认
CustomerModel正确实现了Parcelable接口(你的代码中已在传递Parcelable对象,需保证该类的Parcelable实现无错误)。 - 第一个Fragment的参数传递逻辑无需修改,其功能是正常的。
内容的提问来源于stack exchange,提问作者Hope
相关产品推荐
相关产品推荐

