![](/img/trans.png)
[英]How to use delegate property in MutableStateFlow in jetpack compose
[英]How to observe a MutableStateFlow list in Jetpack Compose
我必須在 Jetpack Compose 上實現 Google 的“地點自動完成”,但問題是一旦我得到地點列表,我就無法更新 UI。
更詳細地說,從 google API 接收到的地點存儲在MutableStateFlow <MutableList <String>>
中,並通過以下方式在可組合函數中觀察狀態: databaseViewModel.autocompletePlaces.collectAsState()
。 但是,當向列表中添加新項目時,不會重新編譯 Composable 函數
獲得名額的類:
class AutocompleteRepository(private val placesClient: PlacesClient)
{
val autocompletePlaces = MutableStateFlow<MutableList<String>>(mutableListOf())
fun fetchPlaces(query: String) {
val token = AutocompleteSessionToken.newInstance()
val request = FindAutocompletePredictionsRequest.builder()
.setSessionToken(token)
.setCountry("IT")
.setQuery(query)
.build()
placesClient.findAutocompletePredictions(request).addOnSuccessListener {
response: FindAutocompletePredictionsResponse ->
autocompletePlaces.value.clear()
for (prediction in response.autocompletePredictions) {
autocompletePlaces.value.add(prediction.getPrimaryText(null).toString())
}
}
}
}
視圖模型:
class DatabaseViewModel(application: Application): AndroidViewModel(application) {
val autocompletePlaces: MutableStateFlow<MutableList<String>>
val autocompleteRepository: AutocompleteRepository
init {
Places.initialize(application, apiKey)
val placesClient = Places.createClient(application)
autocompleteRepository = AutocompleteRepository(placesClient)
autocompletePlaces = autocompleteRepository.autocompletePlaces
}
fun fetchPlaces(query: String)
{
autocompleteRepository.fetchPlaces(query)
}
}
可組合功能:
@Composable
fun dropDownMenu(databaseViewModel: DatabaseViewModel) {
var placeList = databaseViewModel.autocompletePlaces.collectAsState()
//From here on I don't think it's important, but I'll put it in anyway:
var expanded by rememberSaveable { mutableStateOf(true) }
var placeName by rememberSaveable { mutableStateOf("") }
Column {
OutlinedTextField(value = placeName, onValueChange =
{ newText ->
placeName = newText
databaseViewModel.fetchPlaces(newText)
})
DropdownMenu(expanded = expanded,
onDismissRequest = { /*TODO*/ },
properties = PopupProperties(
focusable = false,
dismissOnBackPress = true,
dismissOnClickOutside = true)) {
placeList.value.forEach { item ->
DropdownMenuItem(text = { Text(text = item) },
onClick = {
placeName = item
expanded = false
})
}
}
}
}
編輯:通過更改解決: MutableStateFlow<MutableList<String>>(mutableListOf())
到MutableStateFlow<List<String>>(listOf())
,但我仍然無法理解發生了什么變化,因為列表的結構是之前的代碼也改了
class AutocompleteRepository(private val placesClient: PlacesClient)
{
val autocompletePlaces = MutableStateFlow<List<String>>(listOf()) //Changed
fun fetchPlaces(query: String) {
val token = AutocompleteSessionToken.newInstance()
val request = FindAutocompletePredictionsRequest.builder()
.setSessionToken(token)
.setCountry("IT")
.setQuery(query)
.build()
val temp = mutableListOf<String>()
placesClient.findAutocompletePredictions(request).addOnSuccessListener {
response: FindAutocompletePredictionsResponse ->
for (prediction in response.autocompletePredictions) {
temp.add(prediction.getPrimaryText(null).toString())
}
autocompletePlaces.value = temp //changed
}
}
}
在您的舊代碼中,您只是通過向StateFlow
添加項目來更改 StateFlow 內的MutableList
實例。 這不會觸發更新,因為它仍然是相同的列表(但其中包含額外的值)。
使用您的新代碼,您將StateFlow
的整個值更改為觸發更新的新列表。
您可以將新代碼簡化為:
autocompletePlaces.update {
it + response.autocompletePredictions.map { prediction ->
prediction.getPrimaryText(null).toString()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.