你能告诉我我的方法是否正确吗?它能工作但我不确定它的架构是否正确。我在某处读到我们应该避免在负责创建片段/活动的函数中调用viewmodel函数,主要是因为屏幕方向更改会重新调用网络请求,但我真的需要从一个viewmodel传递参数到另一个viewmodel。重要的是,我正在使用Dagger Hilt依赖注入,因此为每个viewmodel创建工厂并不合理?
假设我有一个项目的RecyclerView,点击后我想启动一个显示详细信息的新片段 - 这是常见的事情。由于这些屏幕的逻辑很复杂,我决定将单个viewmodel分成两个 - 一个用于列表片段,一个用于详细信息片段。
ItemsFragment
有监听器,并使用以下代码启动详细信息片段:
fun onItemSelected(item: Item) {
val args = Bundle().apply {
putInt(KEY_ITEM_ID, item.id)
}
findNavController().navigate(R.id.action_listFragment_to_detailsFragment, args)
}
然后在ItemDetailsFragment
类中的onViewCreated
函数中,我接收传递的参数,将其保存在ItemDetailsViewModel
的itemId
变量中,然后启动requestItemDetails()
函数进行api调用,结果保存到被ItemDetailsFragment
观察的LiveData中。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
//...
val itemId = arguments?.getInt(KEY_ITEM_ID, -1) ?: -1
viewModel.itemId = itemId
viewModel.requestItemDetails()
//...
}
项目详情视图模型
class ItemDetailsViewModel @ViewModelInject constructor(val repository: Repository) : ViewModel() {
var itemId: Int = -1
private val _item = MutableLiveData<Item>()
val item: LiveData<Item> = _item
fun requestItemDetails() {
if (itemId == -1) {
// return error state
return
}
viewModelScope.launch {
val response = repository.getItemDetails(itemId)
//...
_item.postValue(response.data)
}
}
}
findNavController().navigate(R.id.destination, Bundle().apply { putString("key", "value") })
- Sai