标签: kotlin-stateflow

如何正确使用 StateFlow 和 Jetpack compose?

我正在 ViewModel 中进行 API 调用,并在可组合项中观察它,如下所示:

class FancyViewModel(): ViewModel(){
 private val _someUIState =
     MutableStateFlow<FancyWrapper>(FancyWrapper.Nothing)
 val someUIState: StateFlow<FancyWrapper> =
     _someUIState

 fun attemptAPICall() = viewModelScope.launch {
  _someUIState.value = FancyWrapper.Loading
  when(val res = doAPICall()){
   is APIWrapper.Success -> _someUIState.value = FancyWrapper.Loading(res.vaue.data)
   is APIWrapper.Error -> _someUIState.value = FancyWrapper.Error("Error!")
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

在可组合项中,我正在听“someUIState”,如下所示:

@Composable
fun FancyUI(viewModel: FancyViewModel){

 val showProgress by remember {
    mutableStateOf(false)
 }
 val openDialog = remember { mutableStateOf(false) }

 val someUIState =
    viewModel.someUIState.collectAsState()
 
 when(val res = someUIState.value){
  is FancyWrapper.Loading-> showProgress = true
  is FancyWrapper.Success-> { …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack android-jetpack-compose kotlin-stateflow

6
推荐指数
2
解决办法
6797
查看次数

当应用程序处于后台时,flowWithLifecycle(lifecycle, Lifecycle.State.STARTED) 不会停止流程

我正在尝试观察View Collection 和上游流量已停止的结果。但当viewModel.testFlow应用程序在后台时仍在收集。为什么我看不到收集已停止?我观察到了什么错误吗?

视图模型:

val testFlow = flow<Int> {
    for (i in 1..100) {
        delay(1000)
        Timber.e("testFlow: EMIT = $i")
        emit(i)
    }
}
Run Code Online (Sandbox Code Playgroud)

活动:

override fun onViewCreated() {
        lifecycleScope.launch {
            viewModel.testFlow
                .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
                .collect {
                    Timber.d("testFlow: $it Collected")
                }
        }
}

override fun onActivityPaused(activity: Activity) {
    super.onActivityPaused(activity)
    Timber.e("testFlow: onActivityPaused")
}
Run Code Online (Sandbox Code Playgroud)

日志 生命周期图

https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda

android kotlin kotlin-coroutines kotlin-flow kotlin-stateflow

6
推荐指数
1
解决办法
4100
查看次数

MutableStateFlow 不适用于 MutableList

这是我尝试使用的 MutableStateFlow 值:

val songList: MutableStateFlow<MutableList<Song>> = MutableStateFlow(arrayListOf())
Run Code Online (Sandbox Code Playgroud)

我需要观察上面 MutableList 上的更改(在 add、removeAt 等方法之后),但无法实现这一点。我的猜测是,因为只有列表的元素发生变化,而不是列表本身发生变化,所以不会触发收集方法。

如果可能的话,如何使用 StateFlow 实现这一目标?如果不是,正确的做法是什么?

请注意,我需要 arrayListOf() 的初始值,因此 LiveData 对我来说可能不够。

android reactive-programming android-livedata kotlin-stateflow

6
推荐指数
1
解决办法
4162
查看次数

将 mutableState 与 jetpack 结合使用时的最佳实践在视图模型内组合并公开可变状态

我有以下视图模型

@HiltViewModel
class ShareViewModel @Inject constructor(
    private val taskRepository: TaskRepository
): ViewModel() {

    private val searchAppBarStateMutableState: MutableState<SearchAppBarState> = mutableStateOf(SearchAppBarState.CLOSED)
    val searchAppBarState: State<SearchAppBarState> = searchAppBarStateMutableState

    private val listOfTaskMutableStateFlow = MutableStateFlow<List<TodoTaskEntity>>(emptyList())
    val listOfTaskStateFlow = listOfTaskMutableStateFlow.asStateFlow()
}
Run Code Online (Sandbox Code Playgroud)

我从不像上面的例子那样公开 mutableStateFlow。这样做时 SonarLint 会显示警告。

MutableStateFlow" and "MutableSharedFlow" should not be exposed
Run Code Online (Sandbox Code Playgroud)

所以我将同样的技术应用于mutableState

但是,如果我这样做,我不会收到任何警告。

val searchAppBarStateMutableState: MutableState<SearchAppBarState> = mutableStateOf(SearchAppBarState.CLOSED)
Run Code Online (Sandbox Code Playgroud)

只是想知道将 MutableState 与 jetpack compose 结合使用的最佳实践是什么。

kotlin android-jetpack-compose kotlin-stateflow

6
推荐指数
1
解决办法
4913
查看次数

LiveData 转换为 StateFlow / SharedFlow

StateFlow / SharedFlow 中此实时数据转换的等效代码是什么?

val myLiveData: LiveData<MyLiveData> = Transformations
                    .switchMap(_query) {
                        if (it == null) {
                           AbsentLiveData.create()
                        } else {
                           repository.load()
                     }
Run Code Online (Sandbox Code Playgroud)

基本上,我想监听每个查询更改以对返回的内容做出反应。因此,任何类似于使用 StateFlow / SharedFlow 的东西都是受欢迎的。

kotlin android-livedata kotlin-flow kotlin-stateflow kotlin-sharedflow

5
推荐指数
1
解决办法
2601
查看次数

更新 Kotlin StateFlow 而不发出更改

是否可以在不发出更改的情况下更新 Kotlin StateFlow?用例是,当用户缩放图表视图时,我希望在活动恢复时恢复该视图,但在缩放过程中跳过 StateFlow 事件。

kotlin kotlin-stateflow

5
推荐指数
1
解决办法
2214
查看次数

如何在kotlin中打印流量大小

嘿,我是 kotlin flow的新手。我正在尝试打印流量大小。众所周知,列表具有size()功能。我们有类似的flow函数吗?

val list = mutableListof(1,2,3)
println(list.size)
Run Code Online (Sandbox Code Playgroud)

输出

2
Run Code Online (Sandbox Code Playgroud)

我们如何获得流量中的大小值?

dataMutableStateFlow.collectLatest { data ->
   ???
 }
Run Code Online (Sandbox Code Playgroud)

谢谢

kotlin kotlin-flow kotlin-stateflow

5
推荐指数
1
解决办法
2178
查看次数

如何避免 MutableStateFlow kotlin 中的默认值

我在我的项目中使用 MutableStateFlow。当我们初始化 MutableStateFlow 对象时,我们需要给出默认值。

val topics = MutableStateFlow<List<String>>(emptyList())
Run Code Online (Sandbox Code Playgroud)

当我收集这个值时

[null, "Hello", "world"]
Run Code Online (Sandbox Code Playgroud)

我想在适配器中传递这个列表。那么有没有一种方法可以在传入适配器之前删除空对象,或者有没有更好的方法?

viewModel.topics.collect { topicsList ->
    println(topicsList)         // [null, "Hello", "world"]
    adapter.submitList(topicsList)
}
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-flow kotlin-stateflow

5
推荐指数
1
解决办法
7499
查看次数

Jetpack Compose 导航状态无法恢复

我正在努力使用 Jetpack Compose 导航。我遵循 NowInAndroid 架构,但没有正确的行为。我的底部栏中有 4 个目的地,其中之一是 Feed 类型的目的地。在本例中,它调用 Firebase 数据库来获取多个产品。问题是,每次我更改目标(ej -> SearchScreen)并返回到 Feed 时,该(Feed)都不会恢复并再次加载所有数据。有人知道发生了什么事吗?

这是我的 navigationTo 函数 ->

fun navigateToBottomBarRoute(route: String) {
    val topLevelOptions = navOptions {
        popUpTo(navController.graph.findStartDestination().id) {
            saveState = true
        }
        launchSingleTop = true
        restoreState = true
    }
    when (route) {
        HomeSections.FEED.route -> navController.navigateToFeed(navOptions = topLevelOptions)
        HomeSections.SEARCH.route -> navController.navigateToSearch(navOptions = topLevelOptions)
        else -> {}
    }
}
Run Code Online (Sandbox Code Playgroud)

我的提要屏幕 ->

@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun Feed(
    onProductClick: (Long, String) -> Unit,
    onNavigateTo: (String) -> Unit,
    modifier: Modifier = Modifier,
    viewModel: …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-compose kotlin-stateflow jetpack-compose-navigation

5
推荐指数
0
解决办法
544
查看次数

Jetpack 撰写惰性列不与列表重新组合

我有一个存储在Viewmodelvia内的列表Stateflow

class FirstSettingViewModel : ViewModel() {

     private val _mRoomList = MutableStateFlow<List<InitRoom>>(mutableListOf())
     val mRoomList: StateFlow<List<InitRoom>> = _mRoomList
    
     ...
Run Code Online (Sandbox Code Playgroud)

我通过 观察流程collectAsState()。它LazyColumn由可以单击的框组成。

val roomList = mViewModel.mRoomList.collectAsState()

Dialog {

    ...

    LazyColumn(...) {

        items(roomList.value, key = { room -> room.room_seq}) { room ->
          
           Box(Modifier.clickable {
              **mViewModel.selectItem(room)**
           }) {...}
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

当单击事件发生时,viewModel 通过复制列表更改“isSelected”值,如下所示。

fun selectItem(room: InitRoom) = viewModelScope.launch(Dispatchers.IO) {
    try {
        val cpy = mutableListOf<InitRoom>()
        mRoomList.value.forEach {
            cpy.add(it.copy())
        }
        cpy.forEach {
            it.isSelected = it.room_seq == room.room_seq
        } …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack-compose kotlin-stateflow lazycolumn compose-recomposition

5
推荐指数
1
解决办法
1924
查看次数