kotlin Jetpack组成:通知StateFlow中的更改

70gysomp  于 2023-01-21  发布在  Kotlin
关注(0)|答案(1)|浏览(159)

我有一个视图模型,每当用户在顶部应用程序栏的文本字段中输入文本时,它都会获取搜索查询数据字符串。
视图模型如下所示:
ViewModel.kt

class ServicesViewModel(
    private val offlineServiceRepository:ServiceRepository
) : ViewModel() {

    private var searchQuery = mutableStateOf("")

    val servicesUiState: StateFlow<ServicesUiState> = offlineServiceRepository.search(searchQuery.value).map {

        Log.i("SEARCHVALUE", "UPDATE SF: ${searchQuery.value}")
        ServicesUiState.Success(it)
    }
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(TIMEOUT_MILLIS),
            initialValue = ServicesUiState.Loading
        )

fun updateSearchQuery(query: String){
    searchQuery.value = query
    Log.i("SEARCHVALUE", "SQ: ${searchQuery.value}")
}

然后在我的屏幕上:

@Composable
fun ScreenServices(
    viewModel: ServicesViewModel,
    retryAction: () -> Unit,
    navigateToPreCall: (service: Service) -> Unit,
    searchBarValue: String,
    modifier: Modifier = Modifier
) {

    val servicesUiState by viewModel.servicesUiState.collectAsState()

    viewModel.updateSearchQuery(searchBarValue)

    when (servicesUiState) {
        is ServicesUiState.Loading -> LoadingScreen(modifier)
        is ServicesUiState.Success -> ServicesList((servicesUiState as ServicesUiState.Success).services, navigateToPreCall, modifier)
        is ServicesUiState.Error -> ErrorScreen(retryAction, modifier)
    }
}

每次用户键入新文本时,searchBarValue都会成功地从UI屏幕发送到viewModel,searchQuery变量也会相应地更新,但是servicesUiState不会获得更新的searchQuery.value,因此列表不会在UI上更新。
有人能帮助我如何将searchQuery变量传递给视图模型中的servicesUiStateStateFlow变量吗?

nimxete2

nimxete21#

(Mutable)State是一个值保持器类,它可以被观察到变化,并且与jetpack compose一起提供。它类似于KotlinFlow。当你在@Composable函数中使用它时,它会被自动观察到,并且你的@Composable函数会在每次变化时被重新组合。你没有在可组合函数中使用它,所以你必须自己观察它。一种方法是使用snapshotFlow函数将它转换为Flow

private val searchQueryFlow = snapshotFlow { searchQuery.value }
val serviceUiState = searchQueryFlow.map { query ->
    offlineServiceRepository.search(query)
}.map { ... }

不过,在您的情况下,最好使用MutableStateFlow,这里使用MutableState没有多大意义。

相关问题