简体   繁体   English

使用 Compose UI 时如何为每个列表项创建单独的 ViewModel?

[英]How to create separate ViewModels per list item when using Compose UI?

I'm working on a trading app.我正在开发一个交易应用程序。 I need to list the user stocks and their value (profit or loss) among with the total value of the portfolio.我需要在投资组合的总价值中列出用户股票及其价值(损益)。

For the holdings list, in an MVP architecture I would create a presenter for each list item but for this app I decided to use MVVM (Compose, ViewModels and Hilt ).对于馆藏列表,在 MVP 架构中,我将为每个列表项创建一个演示者,但对于这个应用程序,我决定使用 MVVM(Compose、ViewModels 和 Hilt)。 My first idea was to create a different ViewModel for each list item.我的第一个想法是为每个列表项创建不同的 ViewModel。 I'm using hiltViewModel() in the composable method signature to create instances of my ViewModel, however this gives me always the same instance and this is not what I want.我在可组合方法签名中使用hiltViewModel()来创建我的 ViewModel 的实例,但是这总是给我相同的实例,这不是我想要的。 When using MVVM architecture, is what I'm trying to do the correct way or I should use a single ViewModel?使用 MVVM 架构时,我正在尝试以正确的方式进行操作还是应该使用单个 ViewModel? Are you aware about any project I could have a look at?你知道我可以看的任何项目吗? The image below is a super simplification of my actual screen, each cell is complex and that's why I wanted to use a different ViewModel for each cell.下图是我实际屏幕的超级简化,每个单元格都很复杂,这就是为什么我想为每个单元格使用不同的 ViewModel。 Any suggestion is very welcome.任何建议都非常受欢迎。

在此处输入图像描述

Unfortunately, HiltViewModelFactory is not a KeyedFactory .不幸的是, HiltViewModelFactory不是KeyedFactory So as of now it does not support same viewModel with multiple instances.所以到目前为止它不支持具有多个实例的相同 viewModel。

Tracking: https://github.com/google/dagger/issues/2328跟踪: https : //github.com/google/dagger/issues/2328

Hilt doesn't support keyed view models. Hilt不支持键控视图模型。 There's a feature request for keyed view models in Compose, but we had to wait until Hilt supports it. Compose 中存在对键控视图模型的功能请求,但我们不得不等到 Hilt 支持它。

Here's a hacky solution on how to bypass it for now.这是一个关于如何暂时绕过它的hacky解决方案。

You can create a plain view model, which can be used with keys, and pass injections to this view model through Hilt view model:您可以创建一个可与键一起使用的普通视图模型,并通过 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)
        }
    }
}

You have to use Dagger version 2.43 (or newer), it includes the feature/fix to support keys in Hilt ViewModels您必须使用 Dagger 2.43 版(或更高版本),它包含支持 Hilt ViewModels 中的键的功能/修复

https://github.com/google/dagger/releases/tag/dagger-2.43 https://github.com/google/dagger/releases/tag/dagger-2.43

From the release description:从发布描述:

Fixes #2328 and #3232 where getting multiple instances of @HiltViewModel with different keys would cause a crash.修复了 #2328 和 #3232 使用不同键获取多个 @HiltViewModel 实例会导致崩溃的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单击列表项时如何分隔所谓的onListItemClick? - How to separate what is called an onListItemClick when a list item is clicked? Jetpack 撰写分页列表 UI 更新项目 Click - Jetpack compose paginated list UI updation on item Click Jetpack compose ui:如何创建cardview? - Jetpack compose ui : How to create cardview? Jetpack Compose UI:如何创建 SearchView? - Jetpack Compose UI: How to create SearchView? Jetpack UI 组合。 如何创建 FloatingActionButton? - Jetpack UI Compose. How to create FloatingActionButton? 如何检查 Jetpack Compose 中列表项的可见性 - How to check visibility of list item in Jetpack Compose Jetpack Compose:如何创建水平列表 - Jetpack Compose : How to create horizontal list 使用 LazyRow 或 Column 时如何使项目出现在屏幕中央 Jetpack Compose? - How to make item appear in the center of the screen Jetpack Compose when using LazyRow or Column? 如何为公共片段创建不同的视图模型? - How to create different viewModels for a common fragment? 如何在旧的 Android 项目中使用 Android Material Stepper 库进行表单验证,但需要使用 Jetpack compose 创建 UI - How to use Android Material Stepper library for form validation in old Android Project but the UI is need to create by using Jetpack compose
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM