为什么通过`.collectAsState()`方法无法获取最新数据?

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

问题

无法在

.collectAsState()
方法中获取新数据,出现在

代码

LoadFoodItemInfo.kt

该方法被调用。

FoodItemRepository.setDatas(queriedFoodItemVOs)

但是经过上述声明后,

的输出

Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")

LaunchedEffect(Unit) block was called.foodItemVOs:[]

哪里

变量

foodItemVOs
定义如下。

val foodItemVOs by foodItemViewModel.data.collectAsState()

为什么无法通过

collectAsState
中的
StateFlow
方法获取最新数据?

这是我的代码。

LoadFoodItemInfo.kt

@Composable
fun LoadFoodItemInfo(
    context:Context,
    foodItemViewModel: FoodItemViewModel = viewModel(),
    foodViewModel: FoodViewModel = viewModel(),
){
    val TAG = "tag_LoadFoodItemInfo"
    val selectedFoodItemVO by foodItemViewModel.selectedData.collectAsState()
    val foodItemVOs by foodItemViewModel.data.collectAsState()    
    LaunchedEffect(Unit) {
        Log.e(TAG,"-".repeat(50))    
        Log.e(TAG,"In LoadFoodItemInfo function, selectedFoodItemVO:${selectedFoodItemVO}")    
        val queriedFoodItemVOs = foodItemViewModel.selectFoodItemByDiaryIdAndMealCategoryId(selectedFoodItemVO)    
        Log.e(TAG,"In LoadFoodItemInfo function, queriedFoodItemVOs:${queriedFoodItemVOs}")
        if(queriedFoodItemVOs.isEmpty()){                Toast.makeText(context,context.getString(R.string.load_food_item_info_failed), Toast.LENGTH_LONG)
                .show()    
            return@LaunchedEffect    
        }    
// set all elem of the array into repo -- FoodItemRepository.    
        FoodItemRepository.setDatas(queriedFoodItemVOs)            Toast.makeText(context,context.getString(R.string.load_food_item_info_successfully), Toast.LENGTH_LONG)
            .show()    
        Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")    
        UpdateSelectedFoodItemVOs(
            context = context,
            foodItemVOs = foodItemVOs,
            foodViewModel = foodViewModel,
        )
        Log.e(TAG,"-".repeat(50))
    }    
}

FoodItemViewModel.kt

class FoodItemViewModel:ViewModel() {    
    private val repository = FoodItemRepository    
    val data: StateFlow<List<FoodItemVO>> = repository.datasFlow    
    ...
}

FoodItemRepository.kt

object FoodItemRepository {
    val TAG = "tag_MealsOptionRepository"
    private val _datasFlow: MutableStateFlow<MutableList<FoodItemVO>> = MutableStateFlow(mutableListOf())    
    val datasFlow = _datasFlow.asStateFlow()    
    ...    
    fun setDatas(newDatas: List<FoodItemVO>) {
        Log.e(TAG, "~".repeat(50))
            Log.e(TAG, "In setDatas method,newDatas:${newDatas}")
        _datasFlow.value = newDatas.toMutableList()    
        Log.e(TAG, "In setDatas method,_datasFlow.value:${_datasFlow.value}")    
        Log.e(TAG, "~".repeat(50))
    }
    ...
}

这是我执行程序时Logcat的最后一部分内容。

2024-11-10 21:52:43.992 26480-26480 tag\_sendHttpRequest com.example.healthhelper E sendHttpRequest function was finished called.

2024-11-10 21:52:43.992 26480-26480 tag\_sendHttpRequest com.example.healthhelper E --------------------------------------------------

2024-11-10 21:52:43.993 26480-26480 tag\_LoadFoodItemInfo com.example.healthhelper E In LoadFoodItemInfo function, queriedFoodItemVOs:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.993 26480-26480 tag\_MealsO...Repository com.example.healthhelper E ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E In setDatas method,newDatas:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E In setDatas method,\_datasFlow.value:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2024-11-10 21:52:43.998 26480-26480 tag\_LoadFoodItemInfo com.example.healthhelper E LaunchedEffect(Unit) block was called.foodItemVOs:\[\]

2024-11-10 21:52:43.999 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, foodItemVOs:\[\]

2024-11-10 21:52:44.000 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, foodNames:\[\]

2024-11-10 21:52:44.000 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, selectedFoodItemVOs:\[\]

欣赏

任何有关此问题的回复或提示将不胜感激。

我尝试了什么?

  1. 通过

    Logcat
    上的输出查找问题的详细信息。

  2. 阅读

    Jetpack Compose collectAsState() does not work with Flow combine()
    并尝试理解本文中的用法。

我的期望是什么?

随时获取存储库的最新数据(包括更新存储库中

StateFlow
的值后。

附注

我遵循

MVVM
设计模式。

项目地点

该项目位于Github。

https://github.com/junshin4211/HealthHelper/blob/2b9fd8d89bd7a9bb3ee5387d8ebfc9f2e578fbbb/app

但是请注意,它是由 Git 控制的版本,因此不在该组中的其他人可能没有权限访问它。

android kotlin-stateflow
1个回答
0
投票

快速浏览一下您提到的问题,我注意到一些可能有用的解决方案。

如果你想在 Compose 中将 MutableList 观察为

State
,你不仅要使用简单的
State
,还要使用
SnapshotStateList<T>
[link],可以通过内置

获得
public fun <T> mutableStateListOf(): SnapshotStateList<T> 

这是一个例子:

//Creating an instance of a MutableList that is observable and can be snapshot.


@Composable
fun Names() {
    var name by remember { mutableStateOf("user") }
    val names = remember { mutableStateListOf<String>() }

    Column {
        Row {
            BasicTextField(value = name, onValueChange = { name = it })
            Button(onClick = { names.add(name) }) { Text("Add") }
        }
        Text("Added names:")
        Column {
            for (addedName in names) {
                Text(addedName)
            }
        }
    }
}

至于你帖子中所说的部分

阅读 Jetpack ComposecollectAsState() 不能与 Flowcombine() 一起使用,并尝试理解本文中的用法。

.combine()
方法会产生冷流,因此有一个简单的修复方法可以将其变成可以观察到的热StateFlow。

这是一个简单的例子:


data class YourStateHolder(val first: String, val second : String)

val state: StateFlow<YourStateHolder> = combine(
        a, b
    ) { first, second ->
        YourStateHolder(
            first = first, second = second
        )
    }.stateIn(
        viewModelScope, 
        SharingStarted.WhileSubscribed(5000), 
        YourStateHolder("initial_1", "initial_2")
       )

希望对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.