繁体   English   中英

在 Jetpack Compose 中使用 ViewModel 实现 startActivity 的最佳实践

[英]Best practice to implement startActivity using ViewModel in Jetpack Compose

例如,我有这个简单的 Composable function

@Composable
fun TextExample(model: SomeViewModel = viewModel()) {
    TextButton(onClick = { model.onClick() }) {
        Text(text = "Test")
    }
}

某些视图模型:

class SomeViewModel : ViewModel() {
    private val _text = mutableStateOf("Test")
    val text: String
        get() = _text.value

    fun onClick() {
        if (text.isEmpty()) {
            // TODO: need to start some activity
        } else {
            _text.value = ""
        }
    }
}

我单击此按钮,然后 model 必须处理此单击。 在某些情况下,我需要开始另一项活动。 什么是正确的方法来做到这一点?

可能有更好的方法,但你可以考虑我的。

我建议首先使用这样的Sealed Class为“一次性事件”创建数据结构

sealed class Events {
    object ToActivityA: Events()
    object ToActivityB: Events()
    data class ToastMessage(val message: String): Events()
}

在您的 ViewModel 中声明一个将发出这些事件的SharedFlow

private val _events = MutableSharedFlow<Events>()
val events: SharedFlow<Events> = _events

在您的情况下,从您的 onClick viewmodel function 发出一个事件,如下所示

fun onClick() {
    if (text.isEmpty()) {
        viewModelScope.launch {
            _events.emit(Events.ToActivityA) // or ToActivityB, or for a Toast 
        }
    } else {
        _text.value = ""
    }
}

现在在您的可组合项中,只需像这样在LaunchedEffect中观察它

LaunchedEffect(key1 = Unit) {
        viewModel.events.collectLatest {
            when (it) {
                Events.ToActivityA -> {
                    // to activity A
                }
                Events.ToActivityB -> {
                    // to activity B
                }
                is Events.ToastMessage -> {
                    // show toast message
                }
            }
        }
    }

如果您还没有准备好调用 startActivity,我建议您访问这篇文章作为参考。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM