Composable 在改变 MutableState 时保持无限循环<Flow<List<Object>>> value

问题描述 投票:0回答:1

我正在编写一排来自 firebase 的惰性项目。我想要一排按钮来按工作正常的地点类型(例如,商店、餐馆等)进行过滤。由于它们都是完全相同的屏幕,我只是用选定的类别调用它的可组合项,然后我希望能够选择一个新按钮来进一步过滤,但由于某种原因,可组合项陷入了循环.

fun LocationScreen(
    modifier: Modifier = Modifier,
    viewModel: HomeViewModel = hiltViewModel(),
    useCategoryTag: CategoryTags? = null,
    onLocationClick: (String) -> Unit,
    onBackClick: () -> Unit = {}
) {
        val locations = viewModel.getCategoryLocations(useCategoryTag).value.collectAsStateWithLifecycle(emptyList())
        ...

在我看来模型

var locations: MutableState<Flow<List<Location>>> =
        mutableStateOf(emptyFlow())

...
...
...

fun getCategoryLocations(tag: CategoryTags?): MutableState<Flow<List<Location>>> {
        if (tag == null) {
            Log.i("getCategoryLocations","null")
            locations.value = firestoreRepository.locations
        } else {
            Log.i("getCategoryLocations","not null")
            locations.value = firestoreRepository.getLocationCategory(tag, locationTags.toList())
        }
        return locations
    }

我的数据访问(过滤只是一个测试值atm)

override fun getLocationCategory(
        tag: CategoryTags,
        filters: List<LocationTags>
    ): Flow<List<Location>> {
        return firestore.collection(LOCATIONS_COLLECTION)
            .whereEqualTo("category", tag.toString())
            .snapshots()
            .map { snapshot ->
                snapshot.toObjects<Location>()
                    .filter { location -> location.top_tags[0] == "Few People" }
            }
    }

单击按钮时触发的单击是这样的,if null 检查似乎工作得很好(它只是导航)

onClick = {
    if (useCategoryTag == null) {
        viewModel.onCategoryClick(item as CategoryTags, onLocationClick)
    } else {
       viewModel.getCategoryLocations(useCategoryTag)
    }
}

Log 就是这样做的:

2023-03-21 20:47:24.876 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:24.893 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:24.917 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:24.948 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:24.978 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:24.997 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:25.028 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:25.044 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null
2023-03-21 20:47:25.060 13143-13143 getCategoryLocations    com.app.senseaid                     I  not null

曾尝试使用if语句检查是否应该重组但没有任何进展

编辑:现在也是循环初始合成

android kotlin google-cloud-firestore android-jetpack-compose flow
1个回答
1
投票

编辑:Firestore API 似乎无法按照您希望的方式工作。您不能像这样创建动态查询流。相反,您必须创建自己的流程并在手动使用查询时更新它。

试试这个:

在存储库中:

private val _locations = MutableStateFlow<List<Location>>(emptyList<String>())
val locations: StateFlow<List<Location>> = _locations
private val tagFlow: MutableStateFlow<CategoryTags?> = MutableStateFlow(null)
fun updateTag(tag: CategoryTags?) = tagFlow.update { tag }
init {
    coroutineScope.launch { // I assume you have a way to inject a couroutineScope for the repository
        tagFlow.collect { tag ->
            val collection = firestore.collection(LOCATIONS_COLLECTION)
            val query =
                if (tag == null) collection
                else collection.whereEqualTo("category", tag)
            query.get().addOnSuccessListener { snapshot ->
                val newLocations = snapshot.toObjects<Location>()
                    .filter { location -> location.top_tags[0] == "Few People" }
                _locations.update { newLocations }
            }
        }
    }
}

在视图模型中:

val locations = firestoreRepository.locations
fun onCategoryClick(tag: CategoryTags?) = firestoreRepository.updateTag(tag)

在可组合屏幕中:

val locations by viewModel.locations.collectAsStateWithLifecycle()
...
onClick = { viewModel. onCategoryClick(item as CategoryTags) }
© www.soinside.com 2019 - 2024. All rights reserved.