简体   繁体   中英

Best practice to implement startActivity using ViewModel in Jetpack Compose

For example, I have this simple Composable function

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

The SomeViewModel:

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

I clicking this Button and then the model must to handle this click. In some cases I need to start another activity. What is right way to do this?

There might better approach to this but you can consider mine.

Id suggest first to create a data structure for "one time events" with a Sealed Class like this

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

Declare a SharedFlow in your ViewModel that will emit these events

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

and in your case, emit an event from your onClick viewmodel function like this

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

Now in your composable, just observe it in a LaunchedEffect like this

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

If you don't have something prepared yet for calling startActivity, I'd suggest visiting this post as a reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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