kotlin Android Jetpack Compose调用view-model函数仅一次

zqry0prt  于 2023-11-21  发布在  Kotlin
关注(0)|答案(2)|浏览(121)

Activity下有一个屏幕级别的可组合。当用户导航到该屏幕时,我使用LaunchedEffect(Unit) {}调用view-model函数,该函数执行一些工作。现在,它可以正常工作,直到设备旋转或发生任何配置更改。旋转后,LaunchedEffect(Unit) {}再次执行,这是不可取的。
我知道我可以在view-model或composable函数本身中使用一个标志来防止再次执行该操作。但是,在这里写作是为了寻找是否有任何理想的解决方案,因为这似乎是Jetpack Compose中的一个常见问题。
附言:该函数只需要在屏幕级别的视图模型中,而不是在活动级别。此外,不能使用视图模型的init,因为屏幕级别的组合调用的函数需要一些数据作为参数。

b1payxdu

b1payxdu1#

您可以在ViewModel中实现一些基本的缓存。下面是一个假设的例子,说明在配置更改期间,ViewModel将缓存的数据返回给订阅者。

class MainViewModel : ViewModel() {
    sealed interface MainViewState {
        data object Content : MainViewState
        data object Loading : MainViewState
        data class Error(val error: Throwable) : MainViewState
    }

    private val _viewState: MutableStateFlow<MainViewState> =
        MutableStateFlow(MainViewState.Loading)

    val viewState = _viewState.asStateFlow()

    init {
       loadData()
    }

    private fun loadData() = viewModelScope.launch {
        // We have cached data, do nothing, StateFlow will re-emit latest state to new subscribers
        if (_viewState.value == MainViewState.Content) {
            return@launch
        }

        _viewState.update {
            MainViewState.Loading
        }

        // Load some data and return MainViewState.Content or MainViewState.Error
    }
}

字符串

yyyllmsg

yyyllmsg2#

LaunchedEffect将在每次重组时运行。您可以使用rememberSaveable并添加一个标志以不再运行代码。实际上,在viewModel中执行此操作会更准确,但由于您特别希望这样做,因此可以查看此示例。

var workCompleted by rememberSaveable { mutableStateOf(false) }

    LaunchedEffect(Unit) {
        if (!workCompleted) {
            // your work
            workCompleted = true
        }
    }

字符串

相关问题