尝试在@Composable 中获取 ViewModel

问题描述 投票:0回答:3

我正在尝试学习 Jetpack Compose。我坚持使用 ViewModels。

我有一个 ViewModel

class DataViewModel: ViewModel() {

    //the list of live data
    var listData = mutableListOf<Data>()

    //initialize the viewmodel
    init {

        viewModelScope.launch {
            //do the network call (this is working ok)
            val data = fetchData()
            data.forEach {
                listData.add(it)
                //print the list of data, this is working fine
                println("listData")
            }

        }
    }

所以获取数据并将其放入 dataList 工作正常。但不,我想在我的屏幕上显示数据。我做了一个可组合的

@Composable
//pass in the viewmodel
fun DataScreen(model:DataViewModel = viewModel()){
    println("model.listData")
    this return an empty list ?
    Column{
        model.listData?.forEach { item ->

            Text("${item}")

            }
        }

   }

在我的屏幕上没有任何反应,因为它是可组合项中的一个空列表。 我如何从 ViewModel 中获取列表?

android kotlin android-jetpack-compose android-jetpack
3个回答
3
投票

问题是您没有在视图模型中使用 State 值。需要状态才能注册可组合重组的值(以防分配/更改值)

所以你需要有这样的视图模型(我猜你的 fetchData 是一个挂起函数):

   class DataViewModel: ViewModel() {

    //the list of live data
    val listDataState = MutableState<List<Data>> =  mutableStateOf(emptyList<Data>())

    //initialize the viewmodel
    init {

        viewModelScope.launch {
            val data = fetchData()
            listDataState.value = data

        }
    }

    suspend fun fetchData() : List<Data>{
        //something like: 
        return dataRepository.getData()
    }

   }

然后在你的@Composable函数中你得到这样的数据:

val viewModel: DataViewModel = viewModel()
val data = viewModel.listDataState.value

0
投票

目前我在项目中使用这种方式

PokemonDetailScreen.kt

@Composable
fun PokemonDetailScreen(
    dominantColor : Color,
    pokemonName : String,
    navController : NavController,
    topPadding : Dp = 20.dp,
    pokemonImageSize : Dp = 200.dp,
    viewModel : PokemonDetailVm = hiltViewModel()
){

}

PokemonDetailVm.kt

@HiltViewModel
class PokemonDetailVm @Inject constructor(
    private val repository: PokemonRepositoryFeature
): ViewModel(){

    suspend fun getPokemonInfo(pokemonName:String): Resource<Pokemon>{
        return repository.getPokemonInfo(pokemonName)
    }

}

依赖关系

//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.44"
kapt "com.google.dagger:hilt-compiler:2.44"
kapt "com.google.dagger:hilt-android-compiler:2.44"
implementation 'androidx.hilt:hilt-navigation-compose:1.1.0-alpha01'

0
投票

而不是将 viewModel 传递给有趣的 DataScreen。 您可以在下面使用有趣的 DataScreen -

val viewModel = viewModel<DataViewModel>()

为此,在 app build.gradle 中添加以下依赖项 -

implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'

现在您可以使用 viewModel.listData 了。

© www.soinside.com 2019 - 2024. All rights reserved.