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

wfveoks0  于 2022-12-09  发布在  Android
关注(0)|答案(1)|浏览(325)

例如,我有一个简单的组合函数

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

SomeView模型:

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 = ""
        }
    }
}

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

af7jpaap

af7jpaap1#

可能有更好的方法,但你可以考虑我的。
我建议首先用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视图模型函数发出一个事件,如下所示

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做好准备,我建议您访问这篇文章作为参考。

相关问题