我有一个 View 模型,每次用户在顶部应用栏的文本字段中输入文本时,它都会获取搜索查询数据字符串。
View 模型如下:
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
变量传递给我的 View 模型中的 servicesUiState
StateFlow
变量吗?
最佳答案
(Mutable)State
是一个值持有者类,可以观察其变化,并随 jetpack compose 一起提供。它类似于 kotlin Flow
。当您在 @Composable
函数中使用它时,它将被自动观察,并且您的 @Composable
函数将在每次更改时重新组合。您没有在可组合函数中使用它,因此您必须自己观察它。一种方法是使用 snapshotFlow
函数将其转换为Flow
:
private val searchQueryFlow = snapshotFlow { searchQuery.value }
val serviceUiState = searchQueryFlow.map { query ->
offlineServiceRepository.search(query)
}.map { ... }
但就您而言,最好使用 MutableStateFlow
来代替,在这里使用 MutableState
没有多大意义。
关于kotlin - Jetpack 撰写 : Notify changes in StateFlow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75163735/