簡體   English   中英

如何在 Jetpack Compose 中觀察 Mu​​tableStateFlow 列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM