Thread
#compose
    i

    Ink

    1 year ago
    LazyColumn {
        items(postList) {
            Post(
                onPostClick = { post -> PostDetailsScreen() },
                it
            )
        }
    }
    I display list with post. When I select post I want to open new @Composable view with post's details. Now I get error: @Composable invocations can only happen from the context of a @Composable function. Why?
    Filip Wiesner

    Filip Wiesner

    1 year ago
    Because
    onPostClick
    parameter is probably not
    @Composable
    so like the error says, you are not calling it from Composable context. But don't get me wrong, it shouldn't be composable. You need to change your thinking about declarative UI. If
    PostDetailsScreen
    is another screen than you don't probably want to display it inside your
    LazyColumn
    item (because you are calling it inside it now). What you are probably trying to do is to do some kind of navigation and for that you could use the androidx navigation library or just hack something yourself.
    i

    Ink

    1 year ago
    That's 100% true. My solution: • Create enum with destination screens
    enum class Destination{
        PostDetails
        AuthorDetails
    }
    • Create NavController
    val mainNavController = rememberNavController()
    • Handle opening screens in navController
    @Composable
    fun MainNavigationHost(mainNavController: NavController) {
        NavHost(
            navController = mainNavController as NavHostController,
            startDestination = "default"
        ) {
            composable("default") {}
            composable(Destination.PostDetails.name) {
                PostDetailsScreen(postList[2])
            } 
            composable(Destination.AuthorDetails.name) {
                AuthorDetailsScreen()
            }
        }
    }
    • Put destination screen to navController
    LazyColumn {
        items(postList) {
            Post(
                onPostClick = { mainNavController.navigate(Destination.PostDetails.name) },
                it
            )
        }
    }
    i

    Ian Lake

    1 year ago
    Note the specific recommendation to not pass your
    navController
    into your screens, but instead pass down a lambda: https://developer.android.com/jetpack/compose/navigation#testing This means your screen is much easier to test in isolation and you keep all of your navigation code in one place instead of leaking your routes, arguments, etc. into your other classes