状态流 Android Kotlin

State flow Android Kotlin

对于我知道这是错误的每一件事,我都有一个上帝视角模型 但我只是在试验 Flow

我在视图模型中有这两个状态流变量

 private val _currentRestroMenu = MutableStateFlow<State<Menu>>(State.loading())
 private val _userCart = MutableStateFlow(CustomerCart())

 val currentRestroMenu: StateFlow<State<Menu>> = _currentRestroMenu
 val userCart: StateFlow<CustomerCart> = _userCart

下面的函数从服务器获取数据并更新上面的状态流

private fun getRestroMenuFromCloudAndUpdateData(restroId: String) = viewModelScope.launch {
        fireStoreRepository.getRestroMenu(restroId).collect { state ->
            when (state) {
                is State.Success -> {
                    _currentRestroMenu.value = State.success(state.data)
                    dataHolderMenuOnSearch = state.data
                    if (!viewedRestroMenu.contains(state.data)) {
                        viewedRestroMenu.add(state.data)
                    }

                }
                is State.Failed -> {
                    _currentRestroMenu.value = State.failed(state.message)
                }
                is State.Loading -> {
                    _currentRestroMenu.value = State.loading()
                }
            }


        }
    }



private fun getCart() = viewModelScope.launch(Dispatchers.IO) {
        if (currentCart.cartEmpty) {
            fireStoreRepository.getUserCartInfoFromCloud(dataStoreRepository.readFileDataStoreValue.first().savedUserId)
                .collect { cartState ->
                    when (cartState) {
                        is State.Success -> {
                            _userCart.update {
                                it.copy(
                                    cartId = cartState.data.cartId,
                                    cartEmpty = cartState.data.cartEmpty,
                                    cartItem = cartState.data.getCartItem(),
                                    restroId = cartState.data.restroId,
                                    cartTotalAmount = cartState.data.cartTotalAmount,
                                    cartAddressId = cartState.data.cartAddressId,
                                    cartDeliveryTime = cartState.data.cartDeliveryTime,
                                    cartCookingInstructions = cartState.data.cartCookingInstructions,
                                    cartAppliedOfferId = cartState.data.cartAppliedOfferId,
                                    deliveryPartnerTipAmount = cartState.data.deliveryPartnerTipAmount,
                                    cartDeliveryCharge = cartState.data.cartDeliveryCharge,
                                    cartTax = cartState.data.cartTax,
                                    deliveryInstructionId = cartState.data.deliveryInstructionId,
                                    foodHandlingCharge = cartState.data.foodHandlingCharge,
                                    cartNumberOfItems = cartState.data.cartNumberOfItems,
                                    cartRestroName = cartState.data.cartRestroName
                                )
                            }
                            currentCart = cartState.data

                        }
                        is State.Failed -> {
                            if (cartState.message == "Result null") {
                                Log.d(
                                    ContentValues.TAG,
                                    "getCartFromCloud: No cart details found in cloud creating new cart"
                                )
                                _userCart.update {
                                    it.copy(
                                        cartId = dataStoreRepository.readFileDataStoreValue.first().savedUserId,
                                        cartEmpty = true
                                    )
                                }
                                currentCart = CustomerCart(
                                    cartId = dataStoreRepository.readFileDataStoreValue.first().savedUserId,
                                    cartEmpty = true
                                )
                            }
                        }
                        is State.Loading -> {
                            Log.d(ContentValues.TAG, "getCartFromCloud: Loading")
                        }
                    }

                }
        } else {
            _userCart.value = currentCart
            Log.d(ContentValues.TAG, "getCart: $currentCart ")
        }


    }

我正在从不同的片段中收集这些状态流 除一个片段外,一切正常

这是代码

在创建方法中

viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {

                    godCustomerViewModel.currentRestroMenu.collectLatest { menuState ->
                        Log.d(TAG, "currentRestroMenu ::: mENUSELECT FIRED: ")
                        when (menuState) {
                            is State.Success -> {
                                restroMenu = menuState.data
                                binding.recyclerView2.hideShimmer()
                                getCartDetails(restroMenu)
                            }
                            is State.Failed -> {
                                Log.d(TAG, "currentRestroMenu:  ")
                            }
                            is State.Loading -> {
                                binding.recyclerView2.showShimmer()
                            }
                        }
                    }



            }
        }

private fun getCartDetails(restroMenu: Menu) = viewLifecycleOwner.lifecycleScope.launch {
        viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {

            godCustomerViewModel.userCart.collectLatest {

                if (it.restroId == restroMenu.restroId) {

                    categoryAdapterRestroDetails.setData(
                        restroMenu.menuCategories,
                        it.getCartItem()
                    )
                } else {
                    categoryAdapterRestroDetails.setData(
                        restroMenu.menuCategories,
                        ArrayList()
                    )
                }
            }
        }
    }

我正在将收集到的两个值传递给适配器(复古菜单和购物车中的项目)

第一次加载片段时一切正常

我有添加菜品到购物车的功能,可以更新用户购物车的价值

 fun addDishToCart(dish: Dish) = viewModelScope.launch {
        Log.d(ContentValues.TAG, "addDishToCart:  view model invoked")
        if (currentCart.checkIfCartBelongsToThisRestro(dish.dishRestroId)) {
            currentCart.addDishToCart(dish).collect {
                Log.d(ContentValues.TAG, "addDishToCartcollect: $currentCart")
                _userCart.update {
                    it.copy(
                        cartEmpty = currentCart.cartEmpty,
                        cartItem = currentCart.getCartItem(),
                        restroId = currentCart.restroId,
                        cartTotalAmount = currentCart.cartTotalAmount,
                        cartNumberOfItems = currentCart.cartNumberOfItems,

                        )
                }
            }


        } else {
            // restro Conflict
            Log.d(ContentValues.TAG, "addDishToCart: $currentCart")
            _restroConflict.value = CartConflict(true, currentCart.cartRestroName, dish)
        }
        Log.d(ContentValues.TAG, "addDishToCart current cart: ${currentCart.getCartItem()}")
        Log.d(ContentValues.TAG, "addDishToCart: user Cart : ${_userCart.value.getCartItem()} ")

    }

最初也能正常工作

我还有一个按钮可以将菜单过滤为蔬菜非蔬菜

fun filterMenuForVeg(value: Boolean, showAll: Boolean) = viewModelScope.launch {

        if (!showAll) {
            Log.d(ContentValues.TAG, "filterMenuForVeg: Entered veg :$value")

            var filteredMenu = Menu()
            filteredMenu.restroId = dataHolderMenuOnSearch.restroId


            for (menuCategory in dataHolderMenuOnSearch.menuCategories) {
                Log.d(ContentValues.TAG, "filterMenuForVeg: $dataHolderMenuOnSearch ")
                for (dish in menuCategory.dishes) {
                    if (dish.dishVeg == value) {
                        Log.d(ContentValues.TAG, "found dish with veg $value: ")
                        var categoryAlreadySaved = false
                        filteredMenu.menuCategories.filter {
                            categoryAlreadySaved = it.categoryId == menuCategory.categoryId
                            true
                        }
                        if (!categoryAlreadySaved) {
                            Log.d(ContentValues.TAG, "menu category not found in filtered list ")
                            val menuCategoryToAdd = MenuCategories()
                            menuCategoryToAdd.menuCategoryName = menuCategory.menuCategoryName
                            menuCategoryToAdd.categoryId = menuCategory.categoryId
                            menuCategoryToAdd.restroId = menuCategory.restroId
                            menuCategoryToAdd.dishes.add(dish)
                            filteredMenu.menuCategories.add(menuCategoryToAdd)
                        } else {
                            Log.d(ContentValues.TAG, "menu category  found in filtered list ")
                            filteredMenu.menuCategories.find {
                                if (it.categoryId == menuCategory.categoryId) {
                                    it.restroId = menuCategory.restroId
                                    it.dishes.add(dish)
                                }
                                true
                            }
                        }
                    }
                }
            }
            Log.d(ContentValues.TAG, "filterMenuForVeg : $filteredMenu ")
            _currentRestroMenu.value = State.success(filteredMenu)
        } else {
            // set to all data
            _currentRestroMenu.value = State.success(dataHolderMenuOnSearch)
        }

当我过滤蔬菜或非蔬菜的菜肴然后将菜肴添加到购物车(这只会改变 userCart 状态流)我收集这些状态流的地方 被解雇两次 所以设置数据到适配器被调用两次

我做错了什么

你能用 onEach 代替 collectLatest 收集物品吗?它可能会解决你的问题。