如何在Composable函数中正确创建一个ViewModel对象?

How to create a ViewModel object inside composable function correctly?(如何在Composable函数中正确创建一个ViewModel对象?)
本文介绍了如何在Composable函数中正确创建一个ViewModel对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MainActivity中有此结构:

val navController = rememberNavController()
NavHost(
    navController = navController,
    startDestination = ItemsScreen.route
) {
    composable(
        route = ItemsScreen.route
    ) {
        ItemsScreen(
            navController = navController
        )
    }
    composable(
        route = ItemDetailsScreen.route + "/{itemId}",
        arguments = mutableStateListOf(
            navArgument("itemId") {
                type = NavType.StringType
            }
        )
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getString("itemId") ?: ""
        ItemDetailsScreen(
            navController = navController,
            itemId = itemId
        )
    }
}

在ItemDetailsScreen a LazyColumn:

LazyColumn {
    items(
        items = itemsResponse.data
    ) { item ->
        ItemCard(
            item = item,
            onItemClick = {
                navController.navigate(ItemDetailsScreen.route + "/${item.id}")
            }
        )
    }
}

然后单击ItemDetailsScreen导航到ItemDetailsScreen:

fun ItemDetailsScreen(
    navController: NavController,
    itemId: String,
    viewModel: ItemDetailsViewModel = hiltViewModel()
) {
    Log.d(TAG, itemId)
}
如图所示,在构造函数中创建了ViewModel对象。当我打开ItemDetailsScreen时,LOG语句被触发两次。如果我注释此行:

//viewModel: ItemDetailsViewModel = hiltViewModel()

LOG语句按预期工作,它只打印一次ItemID。如何使用ViewModel对象使其只能触发一次LOG语句?

以下也是ViewModel类:

@HiltViewModel
class ItemDetailsViewModel @Inject constructor(
    private val useCases: UseCases
): ViewModel() {
    private val _itemState = mutableStateOf<Response<Item>>(Success(Item()))
    val itemState: State<Response<Item>> = _itemState

    fun getItem(id: String) {
        viewModelScope.launch {
            useCases.getItem(id).collect { response ->
                _itemState.value = response
            }
        }
    }
}

推荐答案

您不必担心日志语句被打印两次。ViewModel创建代码没有任何错误。LOG语句被打印两次,因为它直接位于可组合函数中,而可组合函数会重新组合很多内容(有时甚至以一种不可预测的方式)。如果只想在首次合成Composable时执行某些操作,请将其放入LaunchedEffect块中。 查看documentation以了解有关这些效果处理程序的更多信息。

这篇关于如何在Composable函数中正确创建一个ViewModel对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

How to target newer versions in .gitlab-ci.yml using auto devops (java 11 instead of 8 and Android 31 instead of 29)(如何在.gitlab-ci.yml中使用自动开发工具(Java 11而不是8,Android 31而不是29)瞄准较新的版本)
Android + coreLibraryDesugaring: which Java 11 APIs can I expect to work?(Android+core LibraryDesugering:我可以期待哪些Java 11API能够工作?)
How to render something in an if statement React Native(如何在If语句中呈现某些内容Reaction Native)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)
Using Firebase Firestore in offline only mode(在仅脱机模式下使用Firebase FiRestore)
Crash on Google Play Pre-Launch Report: java.lang.NoSuchMethodError(Google Play发布前崩溃报告:java.lang.NoSuchMethodError)