如何观察JetPack中的MutableStateFlow列表组成
我必须在JetPack撰写上实现Google的“位置自动完成”,但问题是,一旦获得了位置列表,我就无法更新UI。
更详细地说,从Google API接收的位置存储在A mutableStateFlow< mutablelist< string>>>
中,并且状态可通过:databaseviewModel.autococteplaces在可复合函数中观察到。 .CollectasState()
。但是,当将新项目添加到列表中时,可组合函数不是重新编译的
类,可以获取位置:
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())
}
}
}
}
viewModel:
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&lt; mutablelist&lt; string&gt;(mutableListof())
to mutableStateFlow&lt; list&lt; string&lt; string&gt;&gt;&gt;(Listof(Listof()) 't了解发生了什么变化,因为列表的结构在上一个代码中也发生了更改
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
}
}
}
I have to implement Google's "Place Autocomplete" on Jetpack Compose, but the problem is that once I get the list of places, I can't update the UI.
Going into more detail, the places received from the google API are stored in a MutableStateFlow <MutableList <String>>
and the status is observed in a Composable function via: databaseViewModel.autocompletePlaces.collectAsState()
. However, when a new item is added to the list, the Composable function is not re-compiled
Class that gets the places:
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())
}
}
}
}
ViewModel:
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 function:
@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
})
}
}
}
}
EDIT:
solved by changing: MutableStateFlow<MutableList<String>>(mutableListOf())
to MutableStateFlow<List<String>>(listOf())
, but I still can't understand what has changed, since the structure of the list was also changed in the previous code
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
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的旧代码中,您只是通过向其添加项目来更改
mutablelist
实例 stateflow 。这不会触发更新,因为它仍然是相同的列表(但其中包含额外的值)。使用新代码,您将
stateflow
的全部值更改为触发更新的新列表。您可以将新代码简化为类似:
In your old code you were just changing the
MutableList
instance inside theStateFlow
by adding items to it. This does not trigger an update because it is still the same list (but with extra values in it).With your new code you are changing the whole value of the
StateFlow
to a new list which triggers an update.You can simplify your new code to something like: