![](/img/trans.png)
[英]How to separate what is called an onListItemClick when a list item is clicked?
[英]How to create separate ViewModels per list item when using Compose UI?
我正在開發一個交易應用程序。 我需要在投資組合的總價值中列出用戶股票及其價值(損益)。
對於館藏列表,在 MVP 架構中,我將為每個列表項創建一個演示者,但對於這個應用程序,我決定使用 MVVM(Compose、ViewModels 和 Hilt)。 我的第一個想法是為每個列表項創建不同的 ViewModel。 我在可組合方法簽名中使用hiltViewModel()
來創建我的 ViewModel 的實例,但是這總是給我相同的實例,這不是我想要的。 使用 MVVM 架構時,我正在嘗試以正確的方式進行操作還是應該使用單個 ViewModel? 你知道我可以看的任何項目嗎? 下圖是我實際屏幕的超級簡化,每個單元格都很復雜,這就是為什么我想為每個單元格使用不同的 ViewModel。 任何建議都非常受歡迎。
不幸的是, HiltViewModelFactory
不是KeyedFactory
。 所以到目前為止它不支持具有多個實例的相同 viewModel。
Hilt不支持鍵控視圖模型。 Compose 中存在對鍵控視圖模型的功能請求,但我們不得不等到 Hilt 支持它。
這是一個關於如何暫時繞過它的hacky解決方案。
您可以創建一個可與鍵一起使用的普通視圖模型,並通過 Hilt 視圖模型將注入傳遞給該視圖模型:
class SomeInjection @Inject constructor() {
val someValue = 0
}
@HiltViewModel
class InjectionsProvider @Inject constructor(
val someInjection: SomeInjection
): ViewModel() {
}
class SomeViewModel(private val injectionsProvider: InjectionsProvider) : ViewModel() {
val injectedValue get() = injectionsProvider.someInjection.someValue
var storedValue by mutableStateOf("")
private set
fun updateStoredValue(value: String) {
storedValue = value
}
}
@Composable
fun keyedViewModel(key: String) : SomeViewModel {
val injectionsProvider = hiltViewModel<InjectionsProvider>()
return viewModel(
key = key,
factory = object: ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return SomeViewModel(injectionsProvider) as T
}
}
)
}
@Composable
fun TestScreen(
) {
LazyColumn {
items(100) { i ->
val viewModel = keyedViewModel("$i")
Text(viewModel.injectedValue.toString())
TextField(value = viewModel.storedValue, onValueChange = viewModel::updateStoredValue)
}
}
}
您必須使用 Dagger 2.43 版(或更高版本),它包含支持 Hilt ViewModels 中的鍵的功能/修復
https://github.com/google/dagger/releases/tag/dagger-2.43
從發布描述:
修復了 #2328 和 #3232 使用不同鍵獲取多個 @HiltViewModel 實例會導致崩潰的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.